<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>User guide</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="Chapter 1. Boost.Histogram">
<link rel="up" href="../index.html" title="Chapter 1. Boost.Histogram">
<link rel="prev" href="getting_started.html" title="Getting started">
<link rel="next" href="benchmarks.html" title="Benchmarks">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="getting_started.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="benchmarks.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="histogram.guide"></a><a class="link" href="guide.html" title="User guide">User guide</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="guide.html#histogram.guide.making_histograms">Making histograms</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.axis_guide">Axis guide</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.overview">Overview</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.axis_configuration">Axis
        configuration</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="guide.html#histogram.guide.filling_histograms_and_accessing">Filling
      histograms and accessing cells</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.using_profiles">Using profiles</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.using_operators">Using operators</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms">Using algorithms</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.algorithms_from_the_c_standard_l">Algorithms
        from the C++ standard library</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.summation">Summation</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.projection">Projection</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.reduction">Reduction</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="guide.html#histogram.guide.streaming">Streaming</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.serialization">Serialization</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.using_histograms_in_apis">Using histograms
      in APIs</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.expert">Advanced usage</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_axes">User-defined
        axes</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.expert.axis_with_several_arguments">Axis
        with several arguments</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_storage_class">User-defined
        storage class</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.expert.parallelisation_options">Parallelisation
        options</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_accumulators">User-defined
        accumulators</a></span></dt>
</dl></dd>
</dl></div>
<p>
      Boost.Histogram is designed to make simple things simple, yet complex things
      possible. Correspondingly, this guides covers the basic usage first, and the
      advanced usage in later sections. For an alternative quick start guide, have
      a look at the <a class="link" href="getting_started.html" title="Getting started">Getting started</a>
      section.
    </p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="histogram.guide.making_histograms"></a><a class="link" href="guide.html#histogram.guide.making_histograms" title="Making histograms">Making histograms</a>
</h3></div></div></div>
<p>
        A histogram consists of a collection of <a class="link" href="concepts.html#histogram.concepts.Axis" title="Axis">axis
        objects</a> and a <a class="link" href="concepts.html#histogram.concepts.Storage" title="Storage">storage</a>.
        The storage holds a collection of accumulators, one for each cell. The axis
        objects maps input values to indices, which are combined into a global index
        that is used to look up the cell in the storage.
      </p>
<p>
        To start off you do not have to worry about the storage, the library provides
        a good default. Learning more about the many interesting axis types to choose
        from, however, will pay off very quickly (which are discussed further below).
        For now, let us stick to the most common axis, the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular</a></code>
        axis. It represents equidistant intervals on the real line.
      </p>
<p>
        Histograms are created with the convenient factory function <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header &lt;boost/histogram/make_histogram.hpp&gt;">make_histogram</a></code>.
        The following example shows how to make a histogram with a single axis.
      </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="comment">// create a 1d-histogram in default configuration which</span>
  <span class="comment">// covers the real line from -1 to 1 in 100 bins</span>
  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">100</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span>

  <span class="comment">// rank is the number of axes</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">rank</span><span class="special">()</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
        An axis object defines how input values are mapped to bins, it is a mapping
        functor of input values to indices. The axis object holds information such
        as how many bins there are, where the bin edges are, metadata about the axis
        and so on. The rank of a histogram is given by the number of axes. A histogram
        with one axis is one-dimensional. If you provide two, it is two-dimensional,
        and so on.
      </p>
<p>
        In the example above, the compiler knows the number of axes and their type
        at compile-time, the information can be deduced from the arguments to <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header &lt;boost/histogram/make_histogram.hpp&gt;">make_histogram</a></code>. This
        gives the best performance, but sometimes you only know the axis configuration
        at run-time, because it depends on information that's only available at run-time.
        For that case you can also create axes at run-time and pass them to an overload
        of the <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header &lt;boost/histogram/make_histogram.hpp&gt;">make_histogram</a></code>
        function. Here is an example.
      </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&gt;</span>

<span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">config</span> <span class="special">=</span> <span class="string">"4 1.0 2.0\n"</span>
                     <span class="string">"5 3.0 4.0\n"</span><span class="special">;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="comment">// read axis config from a config file (mocked here with std::istringstream)</span>
  <span class="comment">// and create vector of regular axes, the number of axis is not known at compile-time</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">istringstream</span> <span class="identifier">is</span><span class="special">(</span><span class="identifier">config</span><span class="special">);</span>
  <span class="keyword">auto</span> <span class="identifier">v1</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;&gt;();</span>
  <span class="keyword">while</span> <span class="special">(</span><span class="identifier">is</span><span class="special">.</span><span class="identifier">good</span><span class="special">())</span> <span class="special">{</span>
    <span class="keyword">unsigned</span> <span class="identifier">bins</span><span class="special">;</span>
    <span class="keyword">double</span> <span class="identifier">start</span><span class="special">,</span> <span class="identifier">stop</span><span class="special">;</span>
    <span class="identifier">is</span> <span class="special">&gt;&gt;</span> <span class="identifier">bins</span> <span class="special">&gt;&gt;</span> <span class="identifier">start</span> <span class="special">&gt;&gt;</span> <span class="identifier">stop</span><span class="special">;</span>
    <span class="identifier">v1</span><span class="special">.</span><span class="identifier">emplace_back</span><span class="special">(</span><span class="identifier">bins</span><span class="special">,</span> <span class="identifier">start</span><span class="special">,</span> <span class="identifier">stop</span><span class="special">);</span>
  <span class="special">}</span>

  <span class="comment">// create histogram from iterator range</span>
  <span class="comment">// (copying or moving the vector also works, move is shown below)</span>
  <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">v1</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">v1</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">rank</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">v1</span><span class="special">.</span><span class="identifier">size</span><span class="special">());</span>

  <span class="comment">// with a vector of axis::variant (polymorphic axis type that can hold any one of the</span>
  <span class="comment">// template arguments at a time) the types and number of axis can vary at run-time</span>
  <span class="keyword">auto</span> <span class="identifier">v2</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;,</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;&gt;&gt;();</span>
  <span class="identifier">v2</span><span class="special">.</span><span class="identifier">emplace_back</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">100</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span>
  <span class="identifier">v2</span><span class="special">.</span><span class="identifier">emplace_back</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">1</span><span class="special">,</span> <span class="number">7</span><span class="special">));</span>

  <span class="comment">// create dynamic histogram by moving the vector</span>
  <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">v2</span><span class="special">));</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">rank</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
          When the axis types are known at compile-time, the histogram internally
          holds them in a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span></code>, which is very efficient and avoids
          a heap memory allocation. If the number of axes is only known at run-time,
          they are stored in a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>.
          The interface hides this difference very well, but there are a corner cases
          where the difference becomes apparent. The <a class="link" href="overview.html#histogram.overview.structure.host" title="Histogram host class">overview</a>
          has more details on this point.
        </p></td></tr>
</table></div>
<p>
        The factory function named <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header &lt;boost/histogram/make_histogram.hpp&gt;">make_histogram</a></code>
        uses the default storage type, which provides safe counting, is fast, and
        memory efficient. If you want to create a histogram with another storage
        type, use <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header &lt;boost/histogram/make_histogram.hpp&gt;">make_histogram_with</a></code>.
        To learn more about other storage types and how to create your own, have
        a look at the section <a class="link" href="guide.html#histogram.guide.expert" title="Advanced usage">Advanced Usage</a>.
      </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="histogram.guide.axis_guide"></a><a class="link" href="guide.html#histogram.guide.axis_guide" title="Axis guide">Axis guide</a>
</h3></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.overview">Overview</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.axis_configuration">Axis
        configuration</a></span></dt>
</dl></div>
<p>
        The library provides a number of useful axis types. The builtin axis types
        can be configured to fit many needs. If you still need something more exotic,
        no problem, it is easy to write your own axis types, see the <a class="link" href="guide.html#histogram.guide.expert" title="Advanced usage">Advanced
        usage section</a> for details. In the following, we give some advice when
        to use which of the builtin axis types.
      </p>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="histogram.guide.axis_guide.overview"></a><a class="link" href="guide.html#histogram.guide.axis_guide.overview" title="Overview">Overview</a>
</h4></div></div></div>
<div class="variablelist">
<p class="title"><b></b></p>
<dl class="variablelist">
<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular</a></code>
            </span></dt>
<dd><p>
                Axis over intervals on the real line which have equal width. Value-to-index
                conversion is O(1) and very fast. The axis does not allocate memory
                dynamically. The axis is very flexible thanks to transforms (see
                below). Due to finite precision of floating point calculations, bin
                edges may not be exactly at expected values, though. If you need
                bin edges at exactly defined floating point values, use the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">variable</a></code> axis.
                If you need bins at exact consecutive integral values, use the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/integer.html" title="Class template integer">integer</a></code> axis.
              </p></dd>
<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">variable</a></code>
            </span></dt>
<dd><p>
                Axis over intervals on the real line of variable width. Value-to-index
                conversion is O(log(N)). The axis allocates memory dynamically to
                store the bin edges. Use this if the regular axis with transforms
                cannot represent the binning you want. If you need bin edges at exactly
                defined floating point values, use this axis.
              </p></dd>
<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/histogram/axis/integer.html" title="Class template integer">integer</a></code>
            </span></dt>
<dd><p>
                Axis over an integer sequence [i, i+1, i+2, ...]. It can be configured
                to handle real input values, too, and then acts like a fast regular
                axis with a fixed bin width of 1. Value-to-index conversion is O(1)
                and faster than for the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular</a></code>
                axis. Does not allocate memory dynamically. Use this when your input
                consists of an integer range or pre-digitized values with low dynamic
                range, like pixel values for individual colours in an image.
              </p></dd>
<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/histogram/axis/boolean.html" title="Class template boolean">boolean</a></code>
            </span></dt>
<dd><p>
                Axis over the two values [false, true]. It is a common specialization
                of the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular</a></code>
                axis. Value-to-index conversion is a pass-through operation, so this
                is the fastest possible axis. The axis has no state other than the
                metadata (which can be stateless). Does not allocate memory dynamically.
                Use this when your input consists of binary categories, like signal
                and background.
              </p></dd>
<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/histogram/axis/category.html" title="Class template category">category</a></code>
            </span></dt>
<dd><p>
                Axis over a set of unique values of an arbitrary equal-comparable
                type. Value-to-index conversion is O(N), but still faster than the
                O(logN) complexity of the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">variable</a></code>
                axis for N &lt; 10, the typical use case. The axis allocates memory
                from the heap to store the values.
              </p></dd>
</dl>
</div>
<p>
          Here is an example which shows the basic use case for each axis type.
        </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">/</span><span class="identifier">axis</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">limits</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="comment">// make a regular axis with 10 bins over interval from 1.5 to 2.5</span>
  <span class="keyword">auto</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;{</span><span class="number">10</span><span class="special">,</span> <span class="number">1.5</span><span class="special">,</span> <span class="number">2.5</span><span class="special">};</span>
  <span class="comment">// `&lt;&gt;` is needed in C++14 because the axis is templated,</span>
  <span class="comment">// in C++17 you can do: auto r = axis::regular{10, 1.5, 2.5};</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">10</span><span class="special">);</span>
  <span class="comment">// alternatively, you can define the step size with the `step` marker</span>
  <span class="keyword">auto</span> <span class="identifier">r_step</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;{</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">step</span><span class="special">(</span><span class="number">0.1</span><span class="special">),</span> <span class="number">1.5</span><span class="special">,</span> <span class="number">2.5</span><span class="special">};</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_step</span> <span class="special">==</span> <span class="identifier">r</span><span class="special">);</span>

  <span class="comment">// histogram uses the `index` method to convert values to indices</span>
  <span class="comment">// note: intervals of builtin axis types are always semi-open [a, b)</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1.5</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1.6</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">2.4</span><span class="special">)</span> <span class="special">==</span> <span class="number">9</span><span class="special">);</span>
  <span class="comment">// index for a value below the start of the axis is always -1</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1.0</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">infinity</span><span class="special">())</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>
  <span class="comment">// index for a value below the above the end of the axis is always `size()`</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">3.0</span><span class="special">)</span> <span class="special">==</span> <span class="number">10</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">infinity</span><span class="special">())</span> <span class="special">==</span> <span class="number">10</span><span class="special">);</span>
  <span class="comment">// index for not-a-number is also `size()` by convention</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">quiet_NaN</span><span class="special">())</span> <span class="special">==</span> <span class="number">10</span><span class="special">);</span>

  <span class="comment">// make a variable axis with 3 bins [-1.5, 0.1), [0.1, 0.3), [0.3, 10)</span>
  <span class="keyword">auto</span> <span class="identifier">v</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">variable</span><span class="special">&lt;&gt;{-</span><span class="number">1.5</span><span class="special">,</span> <span class="number">0.1</span><span class="special">,</span> <span class="number">0.3</span><span class="special">,</span> <span class="number">10.</span><span class="special">};</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">2.0</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">1.5</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0.3</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">10</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">20</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>

  <span class="comment">// make an integer axis with 3 bins at -1, 0, 1</span>
  <span class="keyword">auto</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;{-</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">};</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">2</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">2</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>

  <span class="comment">// make an integer axis called "foo"</span>
  <span class="keyword">auto</span> <span class="identifier">i_with_label</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;{-</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="string">"foo"</span><span class="special">};</span>
  <span class="comment">// all builtin axis types allow you to pass some optional metadata as the last</span>
  <span class="comment">// argument in the constructor; a string by default, but can be any copyable type</span>

  <span class="comment">// two axis do not compare equal if they differ in their metadata</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span> <span class="special">!=</span> <span class="identifier">i_with_label</span><span class="special">);</span>

  <span class="comment">// integer axis also work well with unscoped enums</span>
  <span class="keyword">enum</span> <span class="special">{</span> <span class="identifier">red</span><span class="special">,</span> <span class="identifier">blue</span> <span class="special">};</span>
  <span class="keyword">auto</span> <span class="identifier">i_for_enum</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;{</span><span class="identifier">red</span><span class="special">,</span> <span class="identifier">blue</span> <span class="special">+</span> <span class="number">1</span><span class="special">};</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i_for_enum</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">red</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i_for_enum</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">blue</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>

  <span class="comment">// make a category axis from a scoped enum and/or if the identifiers are not consecutive</span>
  <span class="keyword">enum</span> <span class="keyword">class</span> <span class="identifier">Bar</span> <span class="special">{</span> <span class="identifier">red</span> <span class="special">=</span> <span class="number">12</span><span class="special">,</span> <span class="identifier">blue</span> <span class="special">=</span> <span class="number">6</span> <span class="special">};</span>
  <span class="keyword">auto</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">category</span><span class="special">&lt;</span><span class="identifier">Bar</span><span class="special">&gt;{</span><span class="identifier">Bar</span><span class="special">::</span><span class="identifier">red</span><span class="special">,</span> <span class="identifier">Bar</span><span class="special">::</span><span class="identifier">blue</span><span class="special">};</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">c</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">Bar</span><span class="special">::</span><span class="identifier">red</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">c</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">Bar</span><span class="special">::</span><span class="identifier">blue</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
  <span class="comment">// c.index(12) is a compile-time error, since the argument must be of type `Bar`</span>

  <span class="comment">// category axis can be created for any copyable and equal-comparable type</span>
  <span class="keyword">auto</span> <span class="identifier">c_str</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">category</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;{</span><span class="string">"red"</span><span class="special">,</span> <span class="string">"blue"</span><span class="special">};</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">c_str</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="string">"red"</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">c_str</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="string">"blue"</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
            All builtin axes over a continuous value range use semi-open intervals
            in their constructors as a convention. As a mnemonic, think of iterator
            ranges from <code class="computeroutput"><span class="identifier">begin</span></code> to
            <code class="computeroutput"><span class="identifier">end</span></code>, where <code class="computeroutput"><span class="identifier">end</span></code> is also never included.
          </p></td></tr>
</table></div>
<p>
          As mentioned in the previous example, you can assign an optional label
          to any axis to keep track of what the axis is about. Assume you have census
          data and you want to investigate how yearly income correlates with age,
          you could do:
        </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="comment">// create a 2d-histogram with an "age" and an "income" axis</span>
  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">20</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">100.0</span><span class="special">,</span> <span class="string">"age in years"</span><span class="special">),</span>
                          <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">20</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">100.0</span><span class="special">,</span> <span class="string">"yearly income in Thousands"</span><span class="special">));</span>

  <span class="comment">// do something with h</span>
<span class="special">}</span>
</pre>
<p>
          Without the metadata it would be difficult to see which axis was covering
          which quantity. Metadata is the only axis property that can be modified
          after construction by the user. Axis objects with different metadata do
          not compare equal.
        </p>
<p>
          By default, strings are used to store the metadata, but any type compatible
          with the <a class="link" href="concepts.html#histogram.concepts.Axis" title="Axis"><span class="bold"><strong>Metadata</strong></span>
          concept</a> can be used.
        </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="histogram.guide.axis_guide.axis_configuration"></a><a class="link" href="guide.html#histogram.guide.axis_guide.axis_configuration" title="Axis configuration">Axis
        configuration</a>
</h4></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.axis_configuration.transforms">Transforms</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.axis_guide.axis_configuration.options">Options</a></span></dt>
</dl></div>
<p>
          All builtin axis types have template arguments for customisation. All arguments
          have reasonable defaults so you can use empty brackets. If your compiler
          supports C++17, you can drop the brackets altogether. Suitable arguments
          are then deduced from the constructor call. The template arguments are
          in order:
        </p>
<div class="variablelist">
<p class="title"><b></b></p>
<dl class="variablelist">
<dt><span class="term">Value</span></dt>
<dd><p>
                The value type is the argument type of the <code class="computeroutput"><span class="identifier">index</span><span class="special">()</span></code> method. An argument passed to the
                axis must be implicitly convertible to this type.
              </p></dd>
<dt><span class="term">Transform (only <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular</a></code>
            axis)</span></dt>
<dd><p>
                A class that implements a monotonic transform between the data space
                and the space in which the bins are equi-distant. Users can define
                their own transforms and use them with the axis.
              </p></dd>
<dt><span class="term">Metadata</span></dt>
<dd><p>
                The axis uses an instance this type to store metadata. It is a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> by default, but it can by
                any copyable type. If you want to save a small amount of stack memory
                per axis, you pass the empty <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">null_type</span></code>
                here.
              </p></dd>
<dt><span class="term">Options</span></dt>
<dd><p>
                <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.axis.option_hpp" title="Header &lt;boost/histogram/axis/option.hpp&gt;">Compile-time options</a></code>
                for the axis. This is used to enable/disable under- and overflow
                bins, to make an axis circular, or to enable dynamic growth of the
                axis beyond the initial range.
              </p></dd>
<dt><span class="term">Allocator (only <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">variable</a></code>
            and <code class="computeroutput"><a class="link" href="../boost/histogram/axis/category.html" title="Class template category">category</a></code>
            axes)</span></dt>
<dd><p>
                Allocator that is used to request memory dynamically to store values.
                If you don't know what an allocator is you can safely ignore this
                argument.
              </p></dd>
</dl>
</div>
<p>
          You can use the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">use_default</span></code> tag type for any of these
          options, except for the Value and Allocator, to use the library default.
        </p>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<a name="histogram.guide.axis_guide.axis_configuration.transforms"></a><a class="link" href="guide.html#histogram.guide.axis_guide.axis_configuration.transforms" title="Transforms">Transforms</a>
</h5></div></div></div>
<p>
            Transforms are a way to customize a <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular</a></code>
            axis. Transforms allow you to chose the faster stack-allocated regular
            axis over the generic <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">variable
            axis</a></code> in some cases. The default is the identity transform
            which does nothing. A common need is a regular binning in the logarithm
            of the input value. This can be achieved with a <code class="computeroutput"><a class="link" href="../boost/histogram/axis/transform/log.html" title="Struct log">log</a></code>
            transform. The follow example shows the builtin transforms.
          </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">/</span><span class="identifier">axis</span><span class="special">/</span><span class="identifier">regular</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">limits</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="comment">// make a regular axis with a log transform over [10, 100), [100, 1000), [1000, 10000)</span>
  <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">transform</span><span class="special">::</span><span class="identifier">log</span><span class="special">&gt;</span> <span class="identifier">r_log</span><span class="special">{</span><span class="number">3</span><span class="special">,</span> <span class="number">10.</span><span class="special">,</span> <span class="number">10000.</span><span class="special">};</span>
  <span class="comment">// log transform:</span>
  <span class="comment">// - useful when values vary dramatically in magnitude, like brightness of stars</span>
  <span class="comment">// - edges are not exactly at 10, 100, 1000, because of finite floating point precision</span>
  <span class="comment">// - values &gt;= 0 but smaller than the starting value of the axis are mapped to -1</span>
  <span class="comment">// - values &lt; 0 are mapped to `size()`, because the result of std::log(value) is NaN</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_log</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">10.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_log</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">100.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_log</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1000.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_log</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_log</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_log</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>

  <span class="comment">// make a regular axis with a sqrt transform over [4, 9), [9, 16), [16, 25)</span>
  <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">transform</span><span class="special">::</span><span class="identifier">sqrt</span><span class="special">&gt;</span> <span class="identifier">r_sqrt</span><span class="special">{</span><span class="number">3</span><span class="special">,</span> <span class="number">4.</span><span class="special">,</span> <span class="number">25.</span><span class="special">};</span>
  <span class="comment">// sqrt transform:</span>
  <span class="comment">// - bin widths are more mildly increasing compared to log transform</span>
  <span class="comment">// - axis starting at value == 0 is ok, sqrt(0) == 0 unlike log transform</span>
  <span class="comment">// - values &lt; 0 are mapped to `size()`, because the result of std::sqrt(value) is NaN</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_sqrt</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_sqrt</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">4.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_sqrt</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">9.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_sqrt</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">16.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_sqrt</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">25.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_sqrt</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>

  <span class="comment">// make a regular axis with a power transform x^1/3 over [1, 8), [8, 27), [27, 64)</span>
  <span class="keyword">using</span> <span class="identifier">pow_trans</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">transform</span><span class="special">::</span><span class="identifier">pow</span><span class="special">;</span>
  <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="identifier">pow_trans</span><span class="special">&gt;</span> <span class="identifier">r_pow</span><span class="special">(</span><span class="identifier">pow_trans</span><span class="special">{</span><span class="number">1.</span> <span class="special">/</span> <span class="number">3.</span><span class="special">},</span> <span class="number">3</span><span class="special">,</span> <span class="number">1.</span><span class="special">,</span> <span class="number">64.</span><span class="special">);</span>
  <span class="comment">// pow transform:</span>
  <span class="comment">// - generalization of the sqrt transform</span>
  <span class="comment">// - starting the axis at value == 0 is ok for power p &gt; 0, 0^p == 0 for p &gt; 0</span>
  <span class="comment">// - values &lt; 0 are mapped to `size()` if power p is not a positive integer</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_pow</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_pow</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_pow</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">8.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_pow</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">27.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_pow</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">64.1</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r_pow</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
            Due to the finite precision of floating point calculations, the bin edges
            of a transformed regular axis may not be exactly at the expected values.
            If you need exact correspondence, use a <code class="computeroutput"><a class="link" href="../boost/histogram/axis/variable.html" title="Class template variable">variable</a></code>
            axis.
          </p>
<p>
            Users may write their own transforms and use them with the builtin <code class="computeroutput"><a class="link" href="../boost/histogram/axis/regular.html" title="Class template regular">regular</a></code> axis, by implementing
            a type that matches the <a class="link" href="concepts.html#histogram.concepts.Transform" title="Transform"><span class="bold"><strong>Transform</strong></span> concept</a>.
          </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<a name="histogram.guide.axis_guide.axis_configuration.options"></a><a class="link" href="guide.html#histogram.guide.axis_guide.axis_configuration.options" title="Options">Options</a>
</h5></div></div></div>
<p>
            <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.axis.option_hpp" title="Header &lt;boost/histogram/axis/option.hpp&gt;">Options</a></code>
            can be used to configure each axis type. The option flags are implemented
            as tag types with the suffix <code class="computeroutput"><span class="identifier">_t</span></code>.
            Each tag type has a corresponding value without the suffix. The values
            have set semantics: You can compute the union with <code class="computeroutput"><span class="keyword">operator</span><span class="special">|</span></code> and the intersection with <code class="computeroutput"><span class="keyword">operator</span><span class="special">&amp;</span></code>.
            When you pass a single option flag to an axis as a template parameter,
            use the tag type. When you need to pass the union of several options
            to an axis as a template parameter, surround the union of option values
            with a <code class="computeroutput"><span class="keyword">decltype</span></code>. Both ways
            of passing options are shown in the following examples.
          </p>
<p>
            <span class="bold"><strong>Under- and overflow bins</strong></span>
          </p>
<p>
            Under- and overflow bins are added automatically for most axis types.
            If you create an axis with 10 bins, the histogram will actually have
            12 bins along that axis. The extra bins are very useful, as explained
            in the <a class="link" href="rationale.html#histogram.rationale.uoflow" title="Under- and overflow bins">rationale</a>. If
            the input cannot exceed the axis range or if you are really tight on
            memory, you can disable the extra bins. A demonstration:
          </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="comment">// create a 1d-histogram over integer values from 1 to 6</span>
  <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="number">1</span><span class="special">,</span> <span class="number">7</span><span class="special">));</span>
  <span class="comment">// axis has size 6...</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">6</span><span class="special">);</span>
  <span class="comment">// ... but histogram has size 8, because of overflow and underflow bins</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">8</span><span class="special">);</span>

  <span class="comment">// create a 1d-histogram for throws of a six-sided die without extra bins,</span>
  <span class="comment">// since the values cannot be smaller than 1 or larger than 6</span>
  <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">use_default</span><span class="special">,</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">option</span><span class="special">::</span><span class="identifier">none_t</span><span class="special">&gt;(</span><span class="number">1</span><span class="special">,</span> <span class="number">7</span><span class="special">));</span>
  <span class="comment">// now size of axis and histogram is equal</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">6</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">6</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
            The <code class="computeroutput"><a class="link" href="../boost/histogram/axis/category.html" title="Class template category">category</a></code>
            axis by default comes only with an overflow bin, which counts all input
            values that are not part of the initial set.
          </p>
<p>
            <span class="bold"><strong>Circular axes</strong></span>
          </p>
<p>
            Each builtin axis except the <code class="computeroutput"><a class="link" href="../boost/histogram/axis/category.html" title="Class template category">category</a></code>
            axis can be made circular. This means that the axis is periodic at its
            ends. This is useful if you want make a histogram over a polar angle.
            Example:
          </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">/</span><span class="identifier">axis</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">limits</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="comment">// make a circular regular axis ... [0, 180), [180, 360), [0, 180) ....</span>
  <span class="keyword">using</span> <span class="identifier">opts</span> <span class="special">=</span> <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">option</span><span class="special">::</span><span class="identifier">overflow</span> <span class="special">|</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">option</span><span class="special">::</span><span class="identifier">circular</span><span class="special">);</span>
  <span class="keyword">auto</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="identifier">use_default</span><span class="special">,</span> <span class="identifier">use_default</span><span class="special">,</span> <span class="identifier">opts</span><span class="special">&gt;{</span><span class="number">2</span><span class="special">,</span> <span class="number">0.</span><span class="special">,</span> <span class="number">360.</span><span class="special">};</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="number">180</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">180</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">360</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">540</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">720</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
  <span class="comment">// special values are mapped to the overflow bin index</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">infinity</span><span class="special">())</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(-</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">infinity</span><span class="special">())</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">quiet_NaN</span><span class="special">())</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>

  <span class="comment">// since the regular axis is the most common circular axis, there exists an alias</span>
  <span class="keyword">auto</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">circular</span><span class="special">&lt;&gt;{</span><span class="number">2</span><span class="special">,</span> <span class="number">0.</span><span class="special">,</span> <span class="number">360.</span><span class="special">};</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">r</span> <span class="special">==</span> <span class="identifier">c</span><span class="special">);</span>

  <span class="comment">// make a circular integer axis</span>
  <span class="keyword">auto</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">use_default</span><span class="special">,</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">option</span><span class="special">::</span><span class="identifier">circular_t</span><span class="special">&gt;{</span><span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">};</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">2</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">3</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">4</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">5</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
            A circular axis cannot have an underflow bin, passing both options together
            generates a compile-time error. Since the highest bin wraps around to
            the lowest bin, there is no possibility for overflow either. However,
            an overflow bin is still added by default if the value is a floating
            point type, to catch NaNs and infinities.
          </p>
<p>
            <span class="bold"><strong>Growing axes</strong></span>
          </p>
<p>
            Each builtin axis has an option to make it grow beyond its initial range
            when a value outside of that range is passed to it, while the default
            behaviour is to count this value in the under- or overflow bins (or to
            discard it). Example:
          </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>

<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="comment">// make a growing regular axis</span>
  <span class="comment">// - it grows new bins with its constant bin width until the value is covered</span>
  <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span>
                                         <span class="identifier">use_default</span><span class="special">,</span>
                                         <span class="identifier">use_default</span><span class="special">,</span>
                                         <span class="identifier">axis</span><span class="special">::</span><span class="identifier">option</span><span class="special">::</span><span class="identifier">growth_t</span><span class="special">&gt;{</span><span class="number">2</span><span class="special">,</span> <span class="number">0.</span><span class="special">,</span> <span class="number">1.</span><span class="special">});</span>
  <span class="comment">// nothing special happens here</span>
  <span class="identifier">h1</span><span class="special">(</span><span class="number">0.1</span><span class="special">);</span>
  <span class="identifier">h1</span><span class="special">(</span><span class="number">0.9</span><span class="special">);</span>
  <span class="comment">// state: [0, 0.5): 1, [0.5, 1.0): 1</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">bin</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">lower</span><span class="special">()</span> <span class="special">==</span> <span class="number">0.0</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">bin</span><span class="special">(</span><span class="number">1</span><span class="special">).</span><span class="identifier">upper</span><span class="special">()</span> <span class="special">==</span> <span class="number">1.0</span><span class="special">);</span>

  <span class="comment">// value below range: axis grows new bins until value is in range</span>
  <span class="identifier">h1</span><span class="special">(-</span><span class="number">0.3</span><span class="special">);</span>
  <span class="comment">// state: [-0.5, 0.0): 1, [0, 0.5): 1, [0.5, 1.0): 1</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">bin</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">lower</span><span class="special">()</span> <span class="special">==</span> <span class="special">-</span><span class="number">0.5</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">bin</span><span class="special">(</span><span class="number">2</span><span class="special">).</span><span class="identifier">upper</span><span class="special">()</span> <span class="special">==</span> <span class="number">1.0</span><span class="special">);</span>

  <span class="identifier">h1</span><span class="special">(</span><span class="number">1.9</span><span class="special">);</span>
  <span class="comment">// state: [-0.5, 0.0): 1, [0, 0.5): 1, [0.5, 1.0): 1, [1.0, 1.5): 0 [1.5, 2.0): 1</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">5</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">bin</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">lower</span><span class="special">()</span> <span class="special">==</span> <span class="special">-</span><span class="number">0.5</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">axis</span><span class="special">().</span><span class="identifier">bin</span><span class="special">(</span><span class="number">4</span><span class="special">).</span><span class="identifier">upper</span><span class="special">()</span> <span class="special">==</span> <span class="number">2.0</span><span class="special">);</span>

  <span class="comment">// make a growing category axis (here strings)</span>
  <span class="comment">// - empty axis is allowed: very useful if categories are not known at the beginning</span>
  <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">category</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span>
                                          <span class="identifier">use_default</span><span class="special">,</span>
                                          <span class="identifier">axis</span><span class="special">::</span><span class="identifier">option</span><span class="special">::</span><span class="identifier">growth_t</span><span class="special">&gt;());</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> <span class="comment">// histogram is empty</span>
  <span class="identifier">h2</span><span class="special">(</span><span class="string">"foo"</span><span class="special">);</span> <span class="comment">// new bin foo, index 0</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
  <span class="identifier">h2</span><span class="special">(</span><span class="string">"bar"</span><span class="special">);</span> <span class="comment">// new bin bar, index 1</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
  <span class="identifier">h2</span><span class="special">(</span><span class="string">"foo"</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">[</span><span class="number">1</span><span class="special">]</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
            This feature can be very convenient, but keep two caveats in mind.
          </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
                Growing axes come with a run-time cost, since the histogram has to
                reallocate memory for all cells when an axis changes its size. Whether
                this performance hit is noticeable depends on your application. This
                is a minor issue, the next is more severe.
              </li>
<li class="listitem">
                If you have unexpected outliers in your data which are far away from
                the normal range, the axis could grow to a huge size and the corresponding
                huge memory request could bring the computer to its knees. This is
                one of the reason why growing axes are not the default.
              </li>
</ul></div>
<p>
            A growing axis can have under- and overflow bins, but these only count
            the special floating point values: positive and negative infinity, and
            NaN.
          </p>
</div>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="histogram.guide.filling_histograms_and_accessing"></a><a class="link" href="guide.html#histogram.guide.filling_histograms_and_accessing" title="Filling histograms and accessing cells">Filling
      histograms and accessing cells</a>
</h3></div></div></div>
<p>
        A histogram has been created and now you want to insert values. This is done
        with the flexible <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45537379237680-bb">call
        operator</a></code> or the <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45537379223024-bb">fill
        method</a></code>, which you typically call in a loop. The <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45537379237680-bb">call operator</a></code>
        accepts <code class="computeroutput"><span class="identifier">N</span></code> arguments or a
        <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span></code> with <code class="computeroutput"><span class="identifier">N</span></code>
        elements, where <code class="computeroutput"><span class="identifier">N</span></code> is equal
        to the number of axes of the histogram. It finds the corresponding bin for
        the input and increments the bin counter by one. The <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45537379223024-bb">fill
        method</a></code> accepts a single iterable over other iterables (which
        must have have elements contiguous in memory) or values, see the method documentation
        for details.
      </p>
<p>
        After the histogram has been filled, use the <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45537379176384-bb">at
        method</a></code> (in analogy to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">::</span><span class="identifier">at</span></code>) to
        access the cell values. It accepts integer indices, one for each axis of
        the histogram.
      </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">functional</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">numeric</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">utility</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">3</span><span class="special">),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">2</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span>

  <span class="comment">// fill histogram, number of arguments must be equal to number of axes,</span>
  <span class="comment">// types must be convertible to axis value type (here integer and double)</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0.2</span><span class="special">);</span> <span class="comment">// increase a cell value by one</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="number">0.5</span><span class="special">);</span> <span class="comment">// increase another cell value by one</span>

  <span class="comment">// fills from a tuple are also supported; passing a tuple of wrong size</span>
  <span class="comment">// causes an error at compile-time or an assertion at runtime in debug mode</span>
  <span class="keyword">auto</span> <span class="identifier">xy</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0.3</span><span class="special">);</span>
  <span class="identifier">h</span><span class="special">(</span><span class="identifier">xy</span><span class="special">);</span>

  <span class="comment">// chunk-wise filling is also supported and more efficient, make some data...</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">xy2</span><span class="special">[</span><span class="number">2</span><span class="special">]</span> <span class="special">=</span> <span class="special">{{</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">5</span><span class="special">},</span> <span class="special">{</span><span class="number">0.8</span><span class="special">,</span> <span class="number">0.4</span><span class="special">,</span> <span class="number">0.7</span><span class="special">}};</span>

  <span class="comment">// ... and call fill method</span>
  <span class="identifier">h</span><span class="special">.</span><span class="identifier">fill</span><span class="special">(</span><span class="identifier">xy2</span><span class="special">);</span>

  <span class="comment">// once histogram is filled, access individual cells using operator[] or at(...)</span>
  <span class="comment">// - operator[] can only accept a single argument in the current version of C++,</span>
  <span class="comment">//   it is convenient when you have a 1D histogram</span>
  <span class="comment">// - at(...) can accept several values, so use this by default</span>
  <span class="comment">// - underflow bins are at index -1, overflow bins at index `size()`</span>
  <span class="comment">// - passing an invalid index triggers a std::out_of_range exception</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(-</span><span class="number">1</span><span class="special">,</span> <span class="special">-</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> <span class="comment">// underflow for axis 0 and 1</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(-</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>  <span class="comment">// underflow for axis 0, normal bin for axis 1</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(-</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>  <span class="comment">// underflow for axis 0, overflow for axis 1</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">3</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>   <span class="comment">// overflow for axis 0, normal bin for axis 1</span>

  <span class="comment">// iteration over values works, but see next example for a better way</span>
  <span class="comment">// - iteration using begin() and end() includes under- and overflow bins</span>
  <span class="comment">// - iteration order is an implementation detail and should not be relied upon</span>
  <span class="keyword">const</span> <span class="keyword">double</span> <span class="identifier">sum</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">accumulate</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">h</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="number">0.0</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">sum</span> <span class="special">==</span> <span class="number">6</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
        For a histogram <code class="computeroutput"><span class="identifier">hist</span></code>, the
        calls <code class="computeroutput"><span class="identifier">hist</span><span class="special">(</span><span class="identifier">weight</span><span class="special">(</span><span class="identifier">w</span><span class="special">),</span> <span class="special">...)</span></code>
        and <code class="computeroutput"><span class="identifier">hist</span><span class="special">(...,</span>
        <span class="identifier">weight</span><span class="special">(</span><span class="identifier">w</span><span class="special">))</span></code> increment
        the bin counter by the value <code class="computeroutput"><span class="identifier">w</span></code>
        instead, where <code class="computeroutput"><span class="identifier">w</span></code> may be an
        integer or floating point number. The helper function <code class="computeroutput"><a class="link" href="../boost/histogram/weight.html" title="Function template weight">weight()</a></code>
        marks this argument as a weight, so that it can be distinguished from the
        other inputs. It can be the first or last argument. You can freely mix calls
        with and without a weight. Calls without <code class="computeroutput"><span class="identifier">weight</span></code>
        act like the weight is <code class="computeroutput"><span class="number">1</span></code>. Why
        weighted increments are sometimes useful is explained <a class="link" href="rationale.html#histogram.rationale.weights" title="Support of weighted fills">in
        the rationale</a>.
      </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
          The default storage loses its no-overflow-guarantee when you pass floating
          point weights, but maintains it for integer weights.
        </p></td></tr>
</table></div>
<p>
        When the weights come from a stochastic process, it is useful to keep track
        of the variance of the sum of weights per cell. A specialized histogram can
        be generated with the <code class="computeroutput"><a class="link" href="../boost/histogram/make_wei_idm45537378925680.html" title="Function template make_weighted_histogram">make_weighted_histogram</a></code>
        factory function which does that.
      </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="comment">// Create a histogram with weight counters that keep track of a variance estimate.</span>
  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_weighted_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">3</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span>

  <span class="identifier">h</span><span class="special">(</span><span class="number">0.0</span><span class="special">,</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">1</span><span class="special">));</span> <span class="comment">// weight 1 goes to first bin</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">0.1</span><span class="special">,</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">2</span><span class="special">));</span> <span class="comment">// weight 2 goes to first bin</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">0.4</span><span class="special">,</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">3</span><span class="special">));</span> <span class="comment">// weight 3 goes to second bin</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">0.5</span><span class="special">,</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">4</span><span class="special">));</span> <span class="comment">// weight 4 goes to second bin</span>

  <span class="comment">// chunk-wise filling is also supported</span>
  <span class="keyword">auto</span> <span class="identifier">x</span> <span class="special">=</span> <span class="special">{</span><span class="number">0.2</span><span class="special">,</span> <span class="number">0.6</span><span class="special">};</span>
  <span class="keyword">auto</span> <span class="identifier">w</span> <span class="special">=</span> <span class="special">{</span><span class="number">5</span><span class="special">,</span> <span class="number">6</span><span class="special">};</span>
  <span class="identifier">h</span><span class="special">.</span><span class="identifier">fill</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">weight</span><span class="special">(</span><span class="identifier">w</span><span class="special">));</span>

  <span class="comment">// Weight counters have methods to access the value (sum of weights) and the variance</span>
  <span class="comment">// (sum of weights squared, why this gives the variance is explained in the rationale)</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">[</span><span class="number">0</span><span class="special">].</span><span class="identifier">value</span><span class="special">()</span> <span class="special">==</span> <span class="number">1</span> <span class="special">+</span> <span class="number">2</span> <span class="special">+</span> <span class="number">5</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">[</span><span class="number">0</span><span class="special">].</span><span class="identifier">variance</span><span class="special">()</span> <span class="special">==</span> <span class="number">1</span> <span class="special">*</span> <span class="number">1</span> <span class="special">+</span> <span class="number">2</span> <span class="special">*</span> <span class="number">2</span> <span class="special">+</span> <span class="number">5</span> <span class="special">*</span> <span class="number">5</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">[</span><span class="number">1</span><span class="special">].</span><span class="identifier">value</span><span class="special">()</span> <span class="special">==</span> <span class="number">3</span> <span class="special">+</span> <span class="number">4</span> <span class="special">+</span> <span class="number">6</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">[</span><span class="number">1</span><span class="special">].</span><span class="identifier">variance</span><span class="special">()</span> <span class="special">==</span> <span class="number">3</span> <span class="special">*</span> <span class="number">3</span> <span class="special">+</span> <span class="number">4</span> <span class="special">*</span> <span class="number">4</span> <span class="special">+</span> <span class="number">6</span> <span class="special">*</span> <span class="number">6</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
        To iterate over all cells, the <code class="computeroutput"><a class="link" href="../boost/histogram/indexed_idm45537379055504.html" title="Function template indexed">indexed</a></code>
        range generator is very convenient and also efficient. For almost all configurations,
        the range generator iterates <span class="emphasis"><em>faster</em></span> than a naive for-loop.
        Under- and overflow are skipped by default.
      </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">format</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">numeric</span><span class="special">&gt;</span> <span class="comment">// for std::accumulate</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>

<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="comment">// make histogram with 2 x 2 = 4 bins (not counting under-/overflow bins)</span>
  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">2</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">2</span><span class="special">,</span> <span class="number">2.0</span><span class="special">,</span> <span class="number">4.0</span><span class="special">));</span>

  <span class="identifier">h</span><span class="special">(</span><span class="identifier">weight</span><span class="special">(</span><span class="number">1</span><span class="special">),</span> <span class="special">-</span><span class="number">0.5</span><span class="special">,</span> <span class="number">2.5</span><span class="special">);</span> <span class="comment">// bin index 0, 0</span>
  <span class="identifier">h</span><span class="special">(</span><span class="identifier">weight</span><span class="special">(</span><span class="number">2</span><span class="special">),</span> <span class="special">-</span><span class="number">0.5</span><span class="special">,</span> <span class="number">3.5</span><span class="special">);</span> <span class="comment">// bin index 0, 1</span>
  <span class="identifier">h</span><span class="special">(</span><span class="identifier">weight</span><span class="special">(</span><span class="number">3</span><span class="special">),</span> <span class="number">0.5</span><span class="special">,</span> <span class="number">2.5</span><span class="special">);</span>  <span class="comment">// bin index 1, 0</span>
  <span class="identifier">h</span><span class="special">(</span><span class="identifier">weight</span><span class="special">(</span><span class="number">4</span><span class="special">),</span> <span class="number">0.5</span><span class="special">,</span> <span class="number">3.5</span><span class="special">);</span>  <span class="comment">// bin index 1, 1</span>

  <span class="comment">// use the `indexed` range adaptor to iterate over all bins;</span>
  <span class="comment">// it is not only more convenient but also faster than a hand-crafted loop!</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span>
    <span class="comment">// x is a special accessor object</span>
    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">);</span> <span class="comment">// current index along first axis</span>
    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">j</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1</span><span class="special">);</span> <span class="comment">// current index along second axis</span>
    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">b0</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">bin</span><span class="special">(</span><span class="number">0</span><span class="special">);</span>  <span class="comment">// current bin interval along first axis</span>
    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">b1</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">bin</span><span class="special">(</span><span class="number">1</span><span class="special">);</span>  <span class="comment">// current bin interval along second axis</span>
    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">v</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">x</span><span class="special">;</span>         <span class="comment">// "dereference" to get the bin value</span>
    <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"%i %i [%2i, %i) [%2i, %i): %i\n"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">i</span> <span class="special">%</span> <span class="identifier">j</span> <span class="special">%</span> <span class="identifier">b0</span><span class="special">.</span><span class="identifier">lower</span><span class="special">()</span> <span class="special">%</span>
              <span class="identifier">b0</span><span class="special">.</span><span class="identifier">upper</span><span class="special">()</span> <span class="special">%</span> <span class="identifier">b1</span><span class="special">.</span><span class="identifier">lower</span><span class="special">()</span> <span class="special">%</span> <span class="identifier">b1</span><span class="special">.</span><span class="identifier">upper</span><span class="special">()</span> <span class="special">%</span> <span class="identifier">v</span><span class="special">;</span>
  <span class="special">}</span>

  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>

  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"0 0 [-1, 0) [ 2, 3): 1\n"</span>
                     <span class="string">"1 0 [ 0, 1) [ 2, 3): 3\n"</span>
                     <span class="string">"0 1 [-1, 0) [ 3, 4): 2\n"</span>
                     <span class="string">"1 1 [ 0, 1) [ 3, 4): 4\n"</span><span class="special">);</span>

  <span class="comment">// `indexed` skips underflow and overflow bins by default, but can be called</span>
  <span class="comment">// with the second argument `coverage::all` to walk over all bins</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os2</span><span class="special">;</span>
  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">,</span> <span class="identifier">coverage</span><span class="special">::</span><span class="identifier">all</span><span class="special">))</span> <span class="special">{</span>
    <span class="identifier">os2</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"%2i %2i: %i\n"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">%</span> <span class="special">*</span><span class="identifier">x</span><span class="special">;</span>
  <span class="special">}</span>

  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os2</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>

  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os2</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"-1 -1: 0\n"</span>
                      <span class="string">" 0 -1: 0\n"</span>
                      <span class="string">" 1 -1: 0\n"</span>
                      <span class="string">" 2 -1: 0\n"</span>

                      <span class="string">"-1  0: 0\n"</span>
                      <span class="string">" 0  0: 1\n"</span>
                      <span class="string">" 1  0: 3\n"</span>
                      <span class="string">" 2  0: 0\n"</span>

                      <span class="string">"-1  1: 0\n"</span>
                      <span class="string">" 0  1: 2\n"</span>
                      <span class="string">" 1  1: 4\n"</span>
                      <span class="string">" 2  1: 0\n"</span>

                      <span class="string">"-1  2: 0\n"</span>
                      <span class="string">" 0  2: 0\n"</span>
                      <span class="string">" 1  2: 0\n"</span>
                      <span class="string">" 2  2: 0\n"</span><span class="special">);</span>
<span class="special">}</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="histogram.guide.using_profiles"></a><a class="link" href="guide.html#histogram.guide.using_profiles" title="Using profiles">Using profiles</a>
</h3></div></div></div>
<p>
        Histograms from this library can do more than counting, they can hold arbitrary
        accumulators which accept samples. We call a histogram with accumulators
        that compute the mean of samples in each cell a <span class="emphasis"><em>profile</em></span>.
        Profiles can be generated with the factory function <code class="computeroutput"><a class="link" href="../boost/histogram/make_pro_idm45537378910608.html" title="Function template make_profile">make_profile</a></code>.
      </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">format</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">tuple</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="comment">// make a profile, it computes the mean of the samples in each histogram cell</span>
  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_profile</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">3</span><span class="special">));</span>

  <span class="comment">// mean is computed from the values marked with the sample() helper function</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">1</span><span class="special">));</span> <span class="comment">// sample goes to cell 0</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">2</span><span class="special">));</span> <span class="comment">// sample goes to cell 0</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">3</span><span class="special">));</span> <span class="comment">// sample goes to cell 1</span>
  <span class="identifier">h</span><span class="special">(</span><span class="identifier">sample</span><span class="special">(</span><span class="number">4</span><span class="special">),</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// sample goes to cell 1; sample can be first or last argument</span>

  <span class="comment">// fills from tuples are also supported, 5 and 6 go to cell 2</span>
  <span class="keyword">auto</span> <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">5</span><span class="special">));</span>
  <span class="keyword">auto</span> <span class="identifier">b</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">sample</span><span class="special">(</span><span class="number">6</span><span class="special">),</span> <span class="number">2</span><span class="special">);</span>
  <span class="identifier">h</span><span class="special">(</span><span class="identifier">a</span><span class="special">);</span>
  <span class="identifier">h</span><span class="special">(</span><span class="identifier">b</span><span class="special">);</span>

  <span class="comment">// builtin accumulators have methods to access their state</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span>
    <span class="comment">// use `.` to access methods of accessor, like `index()`</span>
    <span class="comment">// use `-&gt;` to access methods of accumulator</span>
    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">();</span>
    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">n</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">count</span><span class="special">();</span>     <span class="comment">// how many samples are in this bin</span>
    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">vl</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">();</span>    <span class="comment">// mean value</span>
    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">vr</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">variance</span><span class="special">();</span> <span class="comment">// estimated variance of the mean value</span>
    <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"index %i count %i value %.1f variance %.1f\n"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">i</span> <span class="special">%</span> <span class="identifier">n</span> <span class="special">%</span> <span class="identifier">vl</span> <span class="special">%</span> <span class="identifier">vr</span><span class="special">;</span>
  <span class="special">}</span>

  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>

  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"index 0 count 2 value 1.5 variance 0.5\n"</span>
                     <span class="string">"index 1 count 2 value 3.5 variance 0.5\n"</span>
                     <span class="string">"index 2 count 2 value 5.5 variance 0.5\n"</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
        Just like <code class="computeroutput"><a class="link" href="../boost/histogram/weight.html" title="Function template weight">weight()</a></code>,
        <code class="computeroutput"><a class="link" href="../boost/histogram/sample.html" title="Function template sample">sample()</a></code> is a
        marker function. It must be the first or last argument.
      </p>
<p>
        Weights and samples may be combined, if the accumulators can handle weights.
        When both <code class="computeroutput"><a class="link" href="../boost/histogram/weight.html" title="Function template weight">weight()</a></code>
        and <code class="computeroutput"><a class="link" href="../boost/histogram/sample.html" title="Function template sample">sample()</a></code>
        appear in the <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45537379237680-bb">call
        operator</a></code> or the <code class="computeroutput"><a class="link" href="../boost/histogram/histogram.html#idm45537379223024-bb">fill
        method</a></code>, they can be in any order with respect to other, but
        they must be the first or last arguments. To make a profile which can compute
        weighted means with proper uncertainty estimates, use the <code class="computeroutput"><a class="link" href="../boost/histogram/make_wei_idm45537378898048.html" title="Function template make_weighted_profile">make_weighted_profile</a></code>
        factory function.
      </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">format</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span> <span class="comment">// _c suffix creates compile-time numbers</span>

  <span class="comment">// make 2D weighted profile</span>
  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_weighted_profile</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">));</span>

  <span class="comment">// The mean is computed from the values marked with the sample() helper function.</span>
  <span class="comment">// Weights can be passed as well. The `sample` and `weight` arguments can appear in any</span>
  <span class="comment">// order, but they must be the first or last arguments.</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">1</span><span class="special">));</span>            <span class="comment">// sample goes to cell (0, 0); weight is 1</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">2</span><span class="special">),</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">3</span><span class="special">));</span> <span class="comment">// sample goes to cell (0, 0); weight is 3</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">3</span><span class="special">));</span>            <span class="comment">// sample goes to cell (1, 0); weight is 1</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">4</span><span class="special">));</span>            <span class="comment">// sample goes to cell (1, 0); weight is 1</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">5</span><span class="special">));</span>            <span class="comment">// sample goes to cell (1, 0); weight is 1</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">6</span><span class="special">));</span>            <span class="comment">// sample goes to cell (1, 0); weight is 1</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">4</span><span class="special">),</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">7</span><span class="special">));</span> <span class="comment">// sample goes to cell (1, 1); weight is 4</span>
  <span class="identifier">h</span><span class="special">(</span><span class="identifier">weight</span><span class="special">(</span><span class="number">5</span><span class="special">),</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">8</span><span class="special">),</span> <span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// sample goes to cell (1, 1); weight is 5</span>

  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span>
    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="identifier">_c</span><span class="special">);</span>
    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">j</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1</span><span class="identifier">_c</span><span class="special">);</span>
    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">m</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">();</span>    <span class="comment">// weighted mean</span>
    <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">v</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">variance</span><span class="special">();</span> <span class="comment">// estimated variance of weighted mean</span>
    <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"index %i,%i mean %.1f variance %.1f\n"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">i</span> <span class="special">%</span> <span class="identifier">j</span> <span class="special">%</span> <span class="identifier">m</span> <span class="special">%</span> <span class="identifier">v</span><span class="special">;</span>
  <span class="special">}</span>

  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>

  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"index 0,0 mean 1.8 variance 0.5\n"</span>
                     <span class="string">"index 1,0 mean 3.5 variance 0.5\n"</span>
                     <span class="string">"index 0,1 mean 5.5 variance 0.5\n"</span>
                     <span class="string">"index 1,1 mean 7.6 variance 0.5\n"</span><span class="special">);</span>
<span class="special">}</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="histogram.guide.using_operators"></a><a class="link" href="guide.html#histogram.guide.using_operators" title="Using operators">Using operators</a>
</h3></div></div></div>
<p>
        The following operators are supported for pairs of histograms <code class="computeroutput"><span class="special">+,</span> <span class="special">-,</span> <span class="special">*,</span>
        <span class="special">/,</span> <span class="special">==,</span> <span class="special">!=</span></code>. Histograms can also be multiplied and
        divided by a scalar. Only a subset of the arithmetic operators is available
        when the underlying accumulator only supports that subset.
      </p>
<p>
        The arithmetic operators can only be used when the histograms have the same
        axis configuration. This checked at run-time. An exception is thrown if the
        configurations do not match. Two histograms have the same axis configuration,
        if all axes compare equal, which includes a comparison of their metadata.
        Two histograms compare equal, when their axis configurations and all their
        cell values compare equal.
      </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
          If the metadata type has <code class="computeroutput"><span class="keyword">operator</span><span class="special">==</span></code> defined, it is used in the axis configuration
          comparison. Metadata types without <code class="computeroutput"><span class="keyword">operator</span><span class="special">==</span></code> are considered equal, if they are the
          same type.
        </p></td></tr>
</table></div>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="comment">// make two histograms</span>
  <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">2</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span>
  <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">2</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span>

  <span class="identifier">h1</span><span class="special">(-</span><span class="number">0.5</span><span class="special">);</span> <span class="comment">// counts are: 1 0</span>
  <span class="identifier">h2</span><span class="special">(</span><span class="number">0.5</span><span class="special">);</span>  <span class="comment">// counts are: 0 1</span>

  <span class="comment">// add them</span>
  <span class="keyword">auto</span> <span class="identifier">h3</span> <span class="special">=</span> <span class="identifier">h1</span><span class="special">;</span>
  <span class="identifier">h3</span> <span class="special">+=</span> <span class="identifier">h2</span><span class="special">;</span> <span class="comment">// counts are: 1 1</span>

  <span class="comment">// adding multiple histograms at once is likely to be optimized by the compiler so that</span>
  <span class="comment">// superfluous temporaries avoided, but no guarantees are given; use this equivalent</span>
  <span class="comment">// code when you want to make sure: h4 = h1; h4 += h2; h4 += h3;</span>
  <span class="keyword">auto</span> <span class="identifier">h4</span> <span class="special">=</span> <span class="identifier">h1</span> <span class="special">+</span> <span class="identifier">h2</span> <span class="special">+</span> <span class="identifier">h3</span><span class="special">;</span> <span class="comment">// counts are: 2 2</span>

  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h4</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span> <span class="special">&amp;&amp;</span> <span class="identifier">h4</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>

  <span class="comment">// multiply by number, h4 *= 2 also works</span>
  <span class="keyword">auto</span> <span class="identifier">h5</span> <span class="special">=</span> <span class="identifier">h4</span> <span class="special">*</span> <span class="number">2</span><span class="special">;</span> <span class="comment">// counts are: 4 4</span>

  <span class="comment">// divide by number; s4 /= 4 also works</span>
  <span class="keyword">auto</span> <span class="identifier">h6</span> <span class="special">=</span> <span class="identifier">h5</span> <span class="special">/</span> <span class="number">4</span><span class="special">;</span> <span class="comment">// counts are: 1 1</span>

  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h6</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span> <span class="special">&amp;&amp;</span> <span class="identifier">h6</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h6</span> <span class="special">!=</span> <span class="identifier">h5</span> <span class="special">&amp;&amp;</span> <span class="identifier">h5</span> <span class="special">==</span> <span class="number">4</span> <span class="special">*</span> <span class="identifier">h6</span><span class="special">);</span>

  <span class="comment">// note the special effect of multiplication on weight_storage</span>
  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">weight_storage</span><span class="special">(),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">2</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span>
  <span class="identifier">h</span><span class="special">(-</span><span class="number">0.5</span><span class="special">);</span>

  <span class="comment">// counts are: 1 0</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">==</span> <span class="number">1</span> <span class="special">&amp;&amp;</span> <span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>

  <span class="keyword">auto</span> <span class="identifier">h_sum</span> <span class="special">=</span> <span class="identifier">h</span> <span class="special">+</span> <span class="identifier">h</span><span class="special">;</span>
  <span class="keyword">auto</span> <span class="identifier">h_mul</span> <span class="special">=</span> <span class="number">2</span> <span class="special">*</span> <span class="identifier">h</span><span class="special">;</span>

  <span class="comment">// values are the same as expected...</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h_sum</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">h_mul</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">value</span><span class="special">());</span>
  <span class="comment">// ... but variances differ</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h_sum</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">variance</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span> <span class="special">&amp;&amp;</span> <span class="identifier">h_mul</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">).</span><span class="identifier">variance</span><span class="special">()</span> <span class="special">==</span> <span class="number">4</span><span class="special">);</span>

  <span class="comment">// equality operator checks variances, so histograms are not equal</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h_sum</span> <span class="special">!=</span> <span class="identifier">h_mul</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
          A histogram with default storage converts its cell values to double when
          they are to be multiplied with or divided by a real number, or when a real
          number is added or subtracted. At this point the no-overflow-guarantee
          is lost.
        </p></td></tr>
</table></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
          When the storage tracks weight variances, such as <code class="computeroutput"><a class="link" href="reference.html#boost.histogram.weight_storage">boost::histogram::weight_storage</a></code>,
          adding two copies of a histogram produces a different result than scaling
          the histogram by a factor of two, as shown in the last example. The is
          a consequence of the mathematical properties of variances. They can be
          added like normal numbers, but scaling by <code class="computeroutput"><span class="identifier">s</span></code>
          means that variances are scaled by <code class="computeroutput"><span class="identifier">s</span><span class="special">^</span><span class="number">2</span></code>.
        </p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="histogram.guide.using_algorithms"></a><a class="link" href="guide.html#histogram.guide.using_algorithms" title="Using algorithms">Using algorithms</a>
</h3></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.algorithms_from_the_c_standard_l">Algorithms
        from the C++ standard library</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.summation">Summation</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.projection">Projection</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.using_algorithms.reduction">Reduction</a></span></dt>
</dl></div>
<p>
        The library was designed to work with algorithms from the C++ standard library.
        In addition, a support library of algorithms is included with common operations
        on histograms.
      </p>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="histogram.guide.using_algorithms.algorithms_from_the_c_standard_l"></a><a class="link" href="guide.html#histogram.guide.using_algorithms.algorithms_from_the_c_standard_l" title="Algorithms from the C++ standard library">Algorithms
        from the C++ standard library</a>
</h4></div></div></div>
<p>
          The histogram class has standard random-access iterators which can be used
          with various algorithms from the standard library. Some things need to
          be kept in mind:
        </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
              The histogram iterators also walk over the under- and overflow bins,
              if they are present. To skip the extra bins one should use the fast
              iterators from the <code class="computeroutput"><a class="link" href="../boost/histogram/indexed_idm45537379055504.html" title="Function template indexed">boost::histogram::indexed</a></code>
              range generator instead.
            </li>
<li class="listitem">
              The iteration order for histograms with several axes is an implementation-detail,
              but for histograms with one axis it is guaranteed to be the obvious
              order: bins are accessed in order from the lowest to the highest index.
            </li>
</ul></div>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>

<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">algorithm</span><span class="special">&gt;</span> <span class="comment">// fill, any_of, min_element, max_element</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cmath</span><span class="special">&gt;</span>     <span class="comment">// sqrt</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">numeric</span><span class="special">&gt;</span>   <span class="comment">// partial_sum, inner_product</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="comment">// make histogram that represents a probability density function (PDF)</span>
  <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">4</span><span class="special">,</span> <span class="number">1.0</span><span class="special">,</span> <span class="number">3.0</span><span class="special">));</span>

  <span class="comment">// make indexed range to skip underflow and overflow cells</span>
  <span class="keyword">auto</span> <span class="identifier">ind</span> <span class="special">=</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h1</span><span class="special">);</span>

  <span class="comment">// use std::fill to set all counters to 0.25 (except under- and overflow counters)</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">fill</span><span class="special">(</span><span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="number">0.25</span><span class="special">);</span>

  <span class="comment">// compute the cumulative density function (CDF), overriding cell values</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">partial_sum</span><span class="special">(</span><span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());</span>

  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(-</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0.00</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">0.25</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0.50</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">2</span><span class="special">)</span> <span class="special">==</span> <span class="number">0.75</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">3</span><span class="special">)</span> <span class="special">==</span> <span class="number">1.00</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">4</span><span class="special">)</span> <span class="special">==</span> <span class="number">0.00</span><span class="special">);</span>

  <span class="comment">// use any_of to check if any cell values are smaller than 0.1,</span>
  <span class="keyword">auto</span> <span class="identifier">b</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">any_of</span><span class="special">(</span><span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="special">[](</span><span class="keyword">const</span> <span class="keyword">auto</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">&lt;</span> <span class="number">0.1</span><span class="special">;</span> <span class="special">});</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">b</span> <span class="special">==</span> <span class="keyword">false</span><span class="special">);</span> <span class="comment">// under- and overflow cells are zero, but skipped</span>

  <span class="comment">// find minimum element</span>
  <span class="keyword">auto</span> <span class="identifier">min_it</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">min_element</span><span class="special">(</span><span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
  <span class="identifier">assert</span><span class="special">(*</span><span class="identifier">min_it</span> <span class="special">==</span> <span class="number">0.25</span><span class="special">);</span> <span class="comment">// under- and overflow cells are skipped</span>

  <span class="comment">// find maximum element</span>
  <span class="keyword">auto</span> <span class="identifier">max_it</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">max_element</span><span class="special">(</span><span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
  <span class="identifier">assert</span><span class="special">(*</span><span class="identifier">max_it</span> <span class="special">==</span> <span class="number">1.0</span><span class="special">);</span>

  <span class="comment">// make second PDF</span>
  <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">4</span><span class="special">,</span> <span class="number">1.0</span><span class="special">,</span> <span class="number">4.0</span><span class="special">));</span>
  <span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">=</span> <span class="number">0.1</span><span class="special">;</span>
  <span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">=</span> <span class="number">0.3</span><span class="special">;</span>
  <span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">2</span><span class="special">)</span> <span class="special">=</span> <span class="number">0.2</span><span class="special">;</span>
  <span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">3</span><span class="special">)</span> <span class="special">=</span> <span class="number">0.4</span><span class="special">;</span>

  <span class="comment">// computing cosine similiarity: cos(theta) = A dot B / sqrt((A dot A) * (B dot B))</span>
  <span class="keyword">auto</span> <span class="identifier">ind2</span> <span class="special">=</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h2</span><span class="special">);</span>
  <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">aa</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">inner_product</span><span class="special">(</span><span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="number">0.0</span><span class="special">);</span>
  <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">bb</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">inner_product</span><span class="special">(</span><span class="identifier">ind2</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind2</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">ind2</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="number">0.0</span><span class="special">);</span>
  <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">ab</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">inner_product</span><span class="special">(</span><span class="identifier">ind</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ind</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">ind2</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="number">0.0</span><span class="special">);</span>
  <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">cos_sim</span> <span class="special">=</span> <span class="identifier">ab</span> <span class="special">/</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">sqrt</span><span class="special">(</span><span class="identifier">aa</span> <span class="special">*</span> <span class="identifier">bb</span><span class="special">);</span>

  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">abs</span><span class="special">(</span><span class="identifier">cos_sim</span> <span class="special">-</span> <span class="number">0.967</span><span class="special">)</span> <span class="special">&lt;</span> <span class="number">1e-2</span><span class="special">);</span>
<span class="special">}</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="histogram.guide.using_algorithms.summation"></a><a class="link" href="guide.html#histogram.guide.using_algorithms.summation" title="Summation">Summation</a>
</h4></div></div></div>
<p>
          It is easy to iterate over all histogram cells to compute the sum of cell
          values by hand or to use an algorithm from the standard library to do so,
          but it is not safe. The result may not be accurate or overflow, if the
          sum is represented by an integer type. The library provides <code class="computeroutput"><a class="link" href="../boost/histogram/algorithm/sum.html" title="Function template sum">boost::histogram::algorithm::sum</a></code>
          as a safer, albeit slower, alternative. It uses the <a href="https://en.wikipedia.org/wiki/Kahan_summation_algorithm" target="_top">Neumaier
          algorithm</a> in double precision for integers and floating point cells,
          and does the naive sum otherwise.
        </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="histogram.guide.using_algorithms.projection"></a><a class="link" href="guide.html#histogram.guide.using_algorithms.projection" title="Projection">Projection</a>
</h4></div></div></div>
<p>
          It is sometimes convenient to generate a high-dimensional histogram first
          and then extract smaller or lower-dimensional versions from it. Lower-dimensional
          histograms are obtained by summing the bin contents of the removed axes.
          This is called a <span class="emphasis"><em>projection</em></span>. If the histogram has
          under- and overflow bins along all axes, this operation creates a histogram
          which is identical to one that would have been obtained by filling the
          original data.
        </p>
<p>
          Projection is useful if you found out that there is no interesting structure
          along an axis, so it is not worth keeping that axis around, or if you want
          to visualize 1d or 2d summaries of a high-dimensional histogram.
        </p>
<p>
          The library provides the <code class="computeroutput"><a class="link" href="../boost/histogram/algorithm/project_idm45537378458608.html" title="Function template project">boost::histogram::algorithm::project</a></code>
          function for this purpose. It accepts the original histogram and the indices
          (one or more) of the axes that are kept and returns the lower-dimensional
          histogram. If the histogram is static, meaning the axis configuration is
          known at compile-time, compile-time numbers should be used as indices to
          obtain another static histogram. Using normal numbers or iterators over
          indices produces a histogram with a dynamic axis configuration.
        </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">literals</span><span class="special">;</span> <span class="comment">// enables _c suffix</span>

  <span class="comment">// make a 2d histogram</span>
  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">3</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">));</span>

  <span class="identifier">h</span><span class="special">(-</span><span class="number">0.9</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">0.9</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">0.1</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span>

  <span class="keyword">auto</span> <span class="identifier">hr0</span> <span class="special">=</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">project</span><span class="special">(</span><span class="identifier">h</span><span class="special">,</span> <span class="number">0</span><span class="identifier">_c</span><span class="special">);</span> <span class="comment">// keep only first axis</span>
  <span class="keyword">auto</span> <span class="identifier">hr1</span> <span class="special">=</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">project</span><span class="special">(</span><span class="identifier">h</span><span class="special">,</span> <span class="number">1</span><span class="identifier">_c</span><span class="special">);</span> <span class="comment">// keep only second axis</span>

  <span class="comment">// reduce does not remove counts; returned histograms are summed over</span>
  <span class="comment">// the removed axes, so h, hr0, and hr1 have same number of total counts;</span>
  <span class="comment">// we compute the sum of counts with the sum algorithm</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">h</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span> <span class="special">&amp;&amp;</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">hr0</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span> <span class="special">&amp;&amp;</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">hr1</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>

  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os1</span><span class="special">;</span>
  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span>
    <span class="identifier">os1</span> <span class="special">&lt;&lt;</span> <span class="string">"("</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">", "</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"): "</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">x</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os1</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os1</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"(0, 0): 1\n"</span>
                      <span class="string">"(1, 0): 1\n"</span>
                      <span class="string">"(2, 0): 0\n"</span>
                      <span class="string">"(0, 1): 0\n"</span>
                      <span class="string">"(1, 1): 0\n"</span>
                      <span class="string">"(2, 1): 1\n"</span><span class="special">);</span>

  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os2</span><span class="special">;</span>
  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">hr0</span><span class="special">))</span> <span class="identifier">os2</span> <span class="special">&lt;&lt;</span> <span class="string">"("</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">", -): "</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">x</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os2</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os2</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"(0, -): 1\n"</span>
                      <span class="string">"(1, -): 1\n"</span>
                      <span class="string">"(2, -): 1\n"</span><span class="special">);</span>

  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os3</span><span class="special">;</span>
  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">hr1</span><span class="special">))</span> <span class="identifier">os3</span> <span class="special">&lt;&lt;</span> <span class="string">"(- ,"</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"): "</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">x</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os3</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os3</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"(- ,0): 2\n"</span>
                      <span class="string">"(- ,1): 1\n"</span><span class="special">);</span>
<span class="special">}</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="histogram.guide.using_algorithms.reduction"></a><a class="link" href="guide.html#histogram.guide.using_algorithms.reduction" title="Reduction">Reduction</a>
</h4></div></div></div>
<p>
          A projection removes an axis completely. A less drastic way to obtain a
          smaller histogram is the <code class="computeroutput"><a class="link" href="../boost/histogram/algorithm/reduce_idm45537378407712.html" title="Function template reduce">reduce</a></code>
          function, which allows one to <span class="emphasis"><em>slice</em></span>, <span class="emphasis"><em>shrink</em></span>
          or <span class="emphasis"><em>rebin</em></span> individual axes.
        </p>
<p>
          Shrinking means that the value range of an axis is reduced and the number
          of bins along that axis. Slicing does the same, but is based on axis indices
          while shrinking is based on the axis values. To <span class="emphasis"><em>rebin</em></span>
          means that adjacent bins are merged into larger bins, the histogram is
          made coarser. For N adjacent bins, a new bin is formed which covers the
          common interval of the merged bins and has their added content. These two
          operations can be combined and applied to several axes at once. Doing it
          in one step is much more efficient than doing it in several steps.
        </p>
<p>
          The <code class="computeroutput"><a class="link" href="../boost/histogram/algorithm/reduce_idm45537378407712.html" title="Function template reduce">reduce</a></code>
          function does not change the total count if all modified axes in the histogram
          have underflow and overflow bins. Counts in removed bins are added to the
          corresponding under- and overflow bins. As in case of the <code class="computeroutput"><a class="link" href="../boost/histogram/algorithm/project_idm45537378458608.html" title="Function template project">project</a></code> function,
          such a histogram is guaranteed to be identical to one obtained from filling
          the original data.
        </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
  <span class="comment">// import reduce commands into local namespace to save typing</span>
  <span class="keyword">using</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">rebin</span><span class="special">;</span>
  <span class="keyword">using</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">shrink</span><span class="special">;</span>
  <span class="keyword">using</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">slice</span><span class="special">;</span>

  <span class="comment">// make a 2d histogram</span>
  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">4</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">4.0</span><span class="special">),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">4</span><span class="special">,</span> <span class="special">-</span><span class="number">2.0</span><span class="special">,</span> <span class="number">2.0</span><span class="special">));</span>

  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="special">-</span><span class="number">0.9</span><span class="special">);</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0.9</span><span class="special">);</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="number">0.1</span><span class="special">);</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">3</span><span class="special">,</span> <span class="number">0.1</span><span class="special">);</span>

  <span class="comment">// reduce takes positional commands which are applied to the axes in order</span>
  <span class="comment">// - shrink is applied to the first axis; the new axis range is 0.0 to 3.0</span>
  <span class="comment">// - rebin is applied to the second axis; pairs of adjacent bins are merged</span>
  <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">reduce</span><span class="special">(</span><span class="identifier">h</span><span class="special">,</span> <span class="identifier">shrink</span><span class="special">(</span><span class="number">0.0</span><span class="special">,</span> <span class="number">3.0</span><span class="special">),</span> <span class="identifier">rebin</span><span class="special">(</span><span class="number">2</span><span class="special">));</span>

  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">axis</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">3</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">3.0</span><span class="special">));</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">axis</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">2</span><span class="special">,</span> <span class="special">-</span><span class="number">2.0</span><span class="special">,</span> <span class="number">2.0</span><span class="special">));</span>

  <span class="comment">// reduce does not change the total count if the histogram has underflow/overflow bins</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">h</span><span class="special">)</span> <span class="special">==</span> <span class="number">4</span> <span class="special">&amp;&amp;</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">h2</span><span class="special">)</span> <span class="special">==</span> <span class="number">4</span><span class="special">);</span>

  <span class="comment">// One can also explicitly specify the index of the axis in the histogram on which the</span>
  <span class="comment">// command should act, by using this index as the the first parameter. The position of</span>
  <span class="comment">// the command in the argument list of reduce is then ignored. We use this to slice only</span>
  <span class="comment">// the second axis (axis has index 1 in the histogram) from bin index 2 to 4.</span>
  <span class="keyword">auto</span> <span class="identifier">h3</span> <span class="special">=</span> <span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">reduce</span><span class="special">(</span><span class="identifier">h</span><span class="special">,</span> <span class="identifier">slice</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">4</span><span class="special">));</span>

  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h3</span><span class="special">.</span><span class="identifier">axis</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">h</span><span class="special">.</span><span class="identifier">axis</span><span class="special">(</span><span class="number">0</span><span class="special">));</span> <span class="comment">// unchanged</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h3</span><span class="special">.</span><span class="identifier">axis</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">2</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">2.0</span><span class="special">));</span>
<span class="special">}</span>
</pre>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="histogram.guide.streaming"></a><a class="link" href="guide.html#histogram.guide.streaming" title="Streaming">Streaming</a>
</h3></div></div></div>
<p>
        Simple streaming operators are shipped with the library. They are internally
        used by the unit tests and give simple text representations of axis and histogram
        configurations and show the histogram content. One-dimensional histograms
        are rendered as ASCII drawings. The text representations may be useful for
        debugging or more, but users may want to use their own implementations. Therefore,
        the headers with the builtin implementations are not included by any other
        header of the library. The following example shows the effect of output streaming.
      </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">/</span><span class="identifier">ostream</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>

  <span class="comment">// width of histogram can be set like this; if it is not set, the library attempts to</span>
  <span class="comment">// determine the terminal width and choses the histogram width accordingly</span>
  <span class="identifier">os</span><span class="special">.</span><span class="identifier">width</span><span class="special">(</span><span class="number">78</span><span class="special">);</span>

  <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">5</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">,</span> <span class="string">"axis 1"</span><span class="special">));</span>
  <span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">=</span> <span class="number">2</span><span class="special">;</span>
  <span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">=</span> <span class="number">4</span><span class="special">;</span>
  <span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">2</span><span class="special">)</span> <span class="special">=</span> <span class="number">3</span><span class="special">;</span>
  <span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">4</span><span class="special">)</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span>

  <span class="comment">// 1D histograms are rendered as an ASCII drawing</span>
  <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">h1</span><span class="special">;</span>

  <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">2</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">,</span> <span class="string">"axis 1"</span><span class="special">),</span>
                           <span class="identifier">axis</span><span class="special">::</span><span class="identifier">category</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;({</span><span class="string">"red"</span><span class="special">,</span> <span class="string">"blue"</span><span class="special">},</span> <span class="string">"axis 2"</span><span class="special">));</span>

  <span class="comment">// higher dimensional histograms just have their cell counts listed</span>
  <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">h2</span><span class="special">;</span>

  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>

  <span class="identifier">assert</span><span class="special">(</span>
      <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span>
      <span class="string">"histogram(regular(5, -1, 1, metadata=\"axis 1\", options=underflow | overflow))\n"</span>
      <span class="string">"               ┌─────────────────────────────────────────────────────────────┐\n"</span>
      <span class="string">"[-inf,   -1) 0 │                                                             │\n"</span>
      <span class="string">"[  -1, -0.6) 2 │██████████████████████████████                               │\n"</span>
      <span class="string">"[-0.6, -0.2) 4 │████████████████████████████████████████████████████████████ │\n"</span>
      <span class="string">"[-0.2,  0.2) 3 │█████████████████████████████████████████████                │\n"</span>
      <span class="string">"[ 0.2,  0.6) 0 │                                                             │\n"</span>
      <span class="string">"[ 0.6,    1) 1 │███████████████                                              │\n"</span>
      <span class="string">"[   1,  inf) 0 │                                                             │\n"</span>
      <span class="string">"               └─────────────────────────────────────────────────────────────┘\n"</span>
      <span class="string">"histogram(\n"</span>
      <span class="string">"  regular(2, -1, 1, metadata=\"axis 1\", options=underflow | overflow)\n"</span>
      <span class="string">"  category(\"red\", \"blue\", metadata=\"axis 2\", options=overflow)\n"</span>
      <span class="string">"  (-1 0): 0 ( 0 0): 0 ( 1 0): 0 ( 2 0): 0 (-1 1): 0 ( 0 1): 0\n"</span>
      <span class="string">"  ( 1 1): 0 ( 2 1): 0 (-1 2): 0 ( 0 2): 0 ( 1 2): 0 ( 2 2): 0\n"</span>
      <span class="string">")"</span><span class="special">);</span>
<span class="special">}</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="histogram.guide.serialization"></a><a class="link" href="guide.html#histogram.guide.serialization" title="Serialization">Serialization</a>
</h3></div></div></div>
<p>
        The library supports serialization via <a href="../../../../../libs/serialization/index.html" target="_top">Boost.Serialization</a>.
        The serialization code is not included by the super header <code class="computeroutput"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code>,
        so that the library can be used without Boost.Serialization or with another
        compatible serialization library.
      </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">archive</span><span class="special">/</span><span class="identifier">text_iarchive</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">archive</span><span class="special">/</span><span class="identifier">text_oarchive</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">/</span><span class="identifier">serialization</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="comment">// includes serialization code</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="keyword">auto</span> <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">3</span><span class="special">,</span> <span class="special">-</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">,</span> <span class="string">"axis 0"</span><span class="special">),</span>
                          <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="string">"axis 1"</span><span class="special">));</span>
  <span class="identifier">a</span><span class="special">(</span><span class="number">0.5</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span>

  <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">buf</span><span class="special">;</span> <span class="comment">// to hold persistent representation</span>

  <span class="comment">// store histogram</span>
  <span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">archive</span><span class="special">::</span><span class="identifier">text_oarchive</span> <span class="identifier">oa</span><span class="special">(</span><span class="identifier">os</span><span class="special">);</span>
    <span class="identifier">oa</span> <span class="special">&lt;&lt;</span> <span class="identifier">a</span><span class="special">;</span>
    <span class="identifier">buf</span> <span class="special">=</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">();</span>
  <span class="special">}</span>

  <span class="keyword">auto</span> <span class="identifier">b</span> <span class="special">=</span> <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">a</span><span class="special">)();</span> <span class="comment">// create a default-constructed second histogram</span>

  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">b</span> <span class="special">!=</span> <span class="identifier">a</span><span class="special">);</span> <span class="comment">// b is empty, a is not</span>

  <span class="comment">// load histogram</span>
  <span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">istringstream</span> <span class="identifier">is</span><span class="special">(</span><span class="identifier">buf</span><span class="special">);</span>
    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">archive</span><span class="special">::</span><span class="identifier">text_iarchive</span> <span class="identifier">ia</span><span class="special">(</span><span class="identifier">is</span><span class="special">);</span>
    <span class="identifier">ia</span> <span class="special">&gt;&gt;</span> <span class="identifier">b</span><span class="special">;</span>
  <span class="special">}</span>

  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">b</span> <span class="special">==</span> <span class="identifier">a</span><span class="special">);</span> <span class="comment">// now b is equal to a</span>
<span class="special">}</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="histogram.guide.using_histograms_in_apis"></a><a class="link" href="guide.html#histogram.guide.using_histograms_in_apis" title="Using histograms in APIs">Using histograms
      in APIs</a>
</h3></div></div></div>
<p>
        Letting the compiler deduce the histogram type is recommended, because the
        templated type is tedious to write down explicitly. Functions or methods
        which accept or return histograms should be templated to work with all kinds
        of histograms. It is also possible to write templated versions which accept
        only histograms with dynamic axes or only histograms with static axes. The
        following example demonstrates all this.
      </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>

<span class="comment">// function accepts any histogram and returns a copy</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Axes</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Storage</span><span class="special">&gt;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">&lt;</span><span class="identifier">Axes</span><span class="special">,</span> <span class="identifier">Storage</span><span class="special">&gt;</span> <span class="identifier">any_histogram</span><span class="special">(</span>
    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">&lt;</span><span class="identifier">Axes</span><span class="special">,</span> <span class="identifier">Storage</span><span class="special">&gt;&amp;</span> <span class="identifier">h</span><span class="special">)</span> <span class="special">{</span>
  <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span>
<span class="special">}</span>

<span class="comment">// function only accepts histograms with fixed axis types and returns a copy</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Storage</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Axes</span><span class="special">&gt;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">Axes</span><span class="special">...&gt;,</span> <span class="identifier">Storage</span><span class="special">&gt;</span> <span class="identifier">only_static_histogram</span><span class="special">(</span>
    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">Axes</span><span class="special">...&gt;,</span> <span class="identifier">Storage</span><span class="special">&gt;&amp;</span> <span class="identifier">h</span><span class="special">)</span> <span class="special">{</span>
  <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span>
<span class="special">}</span>

<span class="comment">// function only accepts histograms with dynamic axis types and returns a copy</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Storage</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Axes</span><span class="special">&gt;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="identifier">Axes</span><span class="special">...&gt;&gt;,</span>
                            <span class="identifier">Storage</span><span class="special">&gt;</span>
<span class="identifier">only_dynamic_histogram</span><span class="special">(</span>
    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="identifier">Axes</span><span class="special">...&gt;&gt;,</span>
                                <span class="identifier">Storage</span><span class="special">&gt;&amp;</span> <span class="identifier">h</span><span class="special">)</span> <span class="special">{</span>
  <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span>
<span class="special">}</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="keyword">auto</span> <span class="identifier">histogram_with_static_axes</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">10</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">));</span>

  <span class="keyword">using</span> <span class="identifier">axis_variant</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;,</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;&gt;;</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">axis_variant</span><span class="special">&gt;</span> <span class="identifier">axes</span><span class="special">;</span>
  <span class="identifier">axes</span><span class="special">.</span><span class="identifier">emplace_back</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">5</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">));</span>
  <span class="identifier">axes</span><span class="special">.</span><span class="identifier">emplace_back</span><span class="special">(</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">));</span>
  <span class="keyword">auto</span> <span class="identifier">histogram_with_dynamic_axes</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">axes</span><span class="special">);</span>

  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">any_histogram</span><span class="special">(</span><span class="identifier">histogram_with_static_axes</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">histogram_with_static_axes</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">any_histogram</span><span class="special">(</span><span class="identifier">histogram_with_dynamic_axes</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">histogram_with_dynamic_axes</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">only_static_histogram</span><span class="special">(</span><span class="identifier">histogram_with_static_axes</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">histogram_with_static_axes</span><span class="special">);</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">only_dynamic_histogram</span><span class="special">(</span><span class="identifier">histogram_with_dynamic_axes</span><span class="special">)</span> <span class="special">==</span>
         <span class="identifier">histogram_with_dynamic_axes</span><span class="special">);</span>

  <span class="comment">// does not compile: only_static_histogram(histogram_with_dynamic_axes)</span>
  <span class="comment">// does not compile: only_dynamic_histogram(histogram_with_static_axes)</span>
<span class="special">}</span>
</pre>
<p>
        If the histogram type has to be written down explicitly, the types are constructed
        as follows. In all cases, the <code class="computeroutput"><span class="identifier">default_storage</span></code>
        type argument may be replaced by any other storage type or omitted entirely.
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p class="simpara">
            Histogram with fixed axis types:
          </p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">&lt;</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">axis_type_1</span><span class="special">,</span> <span class="identifier">axis_type_2</span><span class="special">,</span> <span class="special">...,</span> <span class="identifier">axis_type_N</span><span class="special">&gt;</span>
  <span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">default_storage</span>
<span class="special">&gt;</span>
</pre>
</li>
<li class="listitem">
<p class="simpara">
            Histogram with a variable number of the same axis type:
          </p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">&lt;</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span>
    <span class="identifier">axis_type_1</span>
  <span class="special">&gt;</span>
  <span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">default_storage</span>
<span class="special">&gt;</span>
</pre>
</li>
<li class="listitem">
<p class="simpara">
            Histogram with variable axis types:
          </p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">&lt;</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span>
    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">axis</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span>
      <span class="identifier">axis_type_1</span><span class="special">,</span> <span class="identifier">axis_type_2</span><span class="special">,</span> <span class="special">...,</span> <span class="identifier">axis_type_N</span>
    <span class="special">&gt;</span>
  <span class="special">&gt;</span>
  <span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">default_storage</span>
<span class="special">&gt;</span>
</pre>
</li>
</ul></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="histogram.guide.expert"></a><a class="link" href="guide.html#histogram.guide.expert" title="Advanced usage">Advanced usage</a>
</h3></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_axes">User-defined
        axes</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.expert.axis_with_several_arguments">Axis
        with several arguments</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_storage_class">User-defined
        storage class</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.expert.parallelisation_options">Parallelisation
        options</a></span></dt>
<dt><span class="section"><a href="guide.html#histogram.guide.expert.user_defined_accumulators">User-defined
        accumulators</a></span></dt>
</dl></div>
<p>
        The library is customisable and extensible by users. Users can create new
        axis types and use them with the histogram, or implement a custom storage
        policy, or use a builtin storage policy with a custom counter type. The library
        was designed to make this very easy. This section shows how to do this.
      </p>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="histogram.guide.expert.user_defined_axes"></a><a class="link" href="guide.html#histogram.guide.expert.user_defined_axes" title="User-defined axes">User-defined
        axes</a>
</h4></div></div></div>
<p>
          It is easy to make custom axis classes that work with the library. The
          custom axis class must meet the requirements of the <a class="link" href="concepts.html#histogram.concepts.Axis" title="Axis"><span class="bold"><strong>Axis</strong></span> concept</a>.
        </p>
<p>
          Users can create a custom axis by derive from a builtin axis type and customize
          its behavior. The following examples demonstrates a modification of the
          <code class="computeroutput"><a class="link" href="../boost/histogram/axis/integer.html" title="Class template integer">integer axis</a></code>.
        </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="comment">// custom axis, which adapts builtin integer axis</span>
  <span class="keyword">struct</span> <span class="identifier">custom_axis</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;</span> <span class="special">{</span>
    <span class="keyword">using</span> <span class="identifier">value_type</span> <span class="special">=</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*;</span> <span class="comment">// type that is fed to the axis</span>

    <span class="keyword">using</span> <span class="identifier">integer</span><span class="special">::</span><span class="identifier">integer</span><span class="special">;</span> <span class="comment">// inherit ctors of base</span>

    <span class="comment">// the customization point</span>
    <span class="comment">// - accept const char* and convert to int</span>
    <span class="comment">// - then call index method of base class</span>
    <span class="identifier">axis</span><span class="special">::</span><span class="identifier">index_type</span> <span class="identifier">index</span><span class="special">(</span><span class="identifier">value_type</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">integer</span><span class="special">::</span><span class="identifier">index</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">atoi</span><span class="special">(</span><span class="identifier">s</span><span class="special">));</span> <span class="special">}</span>
  <span class="special">};</span>

  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">custom_axis</span><span class="special">(</span><span class="number">3</span><span class="special">,</span> <span class="number">6</span><span class="special">));</span>
  <span class="identifier">h</span><span class="special">(</span><span class="string">"-10"</span><span class="special">);</span>
  <span class="identifier">h</span><span class="special">(</span><span class="string">"3"</span><span class="special">);</span>
  <span class="identifier">h</span><span class="special">(</span><span class="string">"4"</span><span class="special">);</span>
  <span class="identifier">h</span><span class="special">(</span><span class="string">"9"</span><span class="special">);</span>

  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">b</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span>
    <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="string">"bin "</span> <span class="special">&lt;&lt;</span> <span class="identifier">b</span><span class="special">.</span><span class="identifier">index</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">" ["</span> <span class="special">&lt;&lt;</span> <span class="identifier">b</span><span class="special">.</span><span class="identifier">bin</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"] "</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">b</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
  <span class="special">}</span>

  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>

  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"bin 0 [3] 1\n"</span>
                     <span class="string">"bin 1 [4] 1\n"</span>
                     <span class="string">"bin 2 [5] 0\n"</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
          How to make an axis completely from scratch is shown in the next example.
        </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="comment">// stateless axis which returns 1 if the input is even and 0 otherwise</span>
  <span class="keyword">struct</span> <span class="identifier">even_odd_axis</span> <span class="special">{</span>
    <span class="identifier">axis</span><span class="special">::</span><span class="identifier">index_type</span> <span class="identifier">index</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">%</span> <span class="number">2</span><span class="special">;</span> <span class="special">}</span>
    <span class="identifier">axis</span><span class="special">::</span><span class="identifier">index_type</span> <span class="identifier">size</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="number">2</span><span class="special">;</span> <span class="special">}</span>
  <span class="special">};</span>

  <span class="comment">// threshold axis which returns 1 if the input is above threshold</span>
  <span class="keyword">struct</span> <span class="identifier">threshold_axis</span> <span class="special">{</span>
    <span class="identifier">threshold_axis</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">thr</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">{}</span>
    <span class="identifier">axis</span><span class="special">::</span><span class="identifier">index_type</span> <span class="identifier">index</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">x</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">&gt;=</span> <span class="identifier">thr</span><span class="special">;</span> <span class="special">}</span>
    <span class="identifier">axis</span><span class="special">::</span><span class="identifier">index_type</span> <span class="identifier">size</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="number">2</span><span class="special">;</span> <span class="special">}</span>
    <span class="keyword">double</span> <span class="identifier">thr</span><span class="special">;</span>
  <span class="special">};</span>

  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">even_odd_axis</span><span class="special">(),</span> <span class="identifier">threshold_axis</span><span class="special">(</span><span class="number">3.0</span><span class="special">));</span>

  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">2.0</span><span class="special">);</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">4.0</span><span class="special">);</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="number">4.0</span><span class="special">);</span>

  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// even, below threshold</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// even, above threshold</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> <span class="comment">// odd, below threshold</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// odd, above threshold</span>
<span class="special">}</span>
</pre>
<p>
          Such minimal axis types lack many features provided by the builtin axis
          types, for example, one cannot iterate over them, but this functionality
          can be added as needed.
        </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="histogram.guide.expert.axis_with_several_arguments"></a><a class="link" href="guide.html#histogram.guide.expert.axis_with_several_arguments" title="Axis with several arguments">Axis
        with several arguments</a>
</h4></div></div></div>
<p>
          Multi-dimensional histograms usually have an orthogonal system of axes.
          Orthogonal means that each axis takes care of only one value and computes
          its local index independently of all the other axes and values. A checker-board
          is such an orthogonal grid in 2D.
        </p>
<p>
          There are other interesting grids which are not orthogonal, notably the
          honeycomb grid. In such a grid, each cell is hexagonal and even though
          the cells form a perfectly regular pattern, it is not possible to sort
          values into these cells using two orthogonal axes.
        </p>
<p>
          The library supports non-orthogonal grids by allowing axis types to accept
          a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span></code> of values. The axis can compute
          an index from the values passed to it in an arbitrary way. The following
          example demonstrates this.
        </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="comment">// axis which returns 1 if the input falls inside the unit circle and zero otherwise</span>
  <span class="keyword">struct</span> <span class="identifier">circle_axis</span> <span class="special">{</span>
    <span class="comment">// accepts a 2D point in form of a std::tuple</span>
    <span class="identifier">axis</span><span class="special">::</span><span class="identifier">index_type</span> <span class="identifier">index</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;&amp;</span> <span class="identifier">point</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span>
      <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">point</span><span class="special">);</span>
      <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">y</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;(</span><span class="identifier">point</span><span class="special">);</span>
      <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span> <span class="special">*</span> <span class="identifier">y</span> <span class="special">&lt;=</span> <span class="number">1.0</span><span class="special">;</span>
    <span class="special">}</span>

    <span class="identifier">axis</span><span class="special">::</span><span class="identifier">index_type</span> <span class="identifier">size</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="number">2</span><span class="special">;</span> <span class="special">}</span>
  <span class="special">};</span>

  <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">circle_axis</span><span class="special">());</span>

  <span class="comment">// fill looks normal for a histogram which has only one Nd-axis</span>
  <span class="identifier">h1</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span>   <span class="comment">// in</span>
  <span class="identifier">h1</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>  <span class="comment">// in</span>
  <span class="identifier">h1</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span>   <span class="comment">// in</span>
  <span class="identifier">h1</span><span class="special">(-</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span>  <span class="comment">// in</span>
  <span class="identifier">h1</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span>   <span class="comment">// in</span>
  <span class="identifier">h1</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span>   <span class="comment">// out</span>
  <span class="identifier">h1</span><span class="special">(-</span><span class="number">1</span><span class="special">,</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span> <span class="comment">// out</span>

  <span class="comment">// 2D histogram, but only 1D index</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span> <span class="comment">// out</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h1</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">5</span><span class="special">);</span> <span class="comment">// in</span>

  <span class="comment">// other axes can be combined with a Nd-axis</span>
  <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram</span><span class="special">(</span><span class="identifier">circle_axis</span><span class="special">(),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">category</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;({</span><span class="string">"red"</span><span class="special">,</span> <span class="string">"blue"</span><span class="special">}));</span>

  <span class="comment">// now we need to pass arguments for Nd-axis explicitly as std::tuple</span>
  <span class="identifier">h2</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">),</span> <span class="string">"red"</span><span class="special">);</span>
  <span class="identifier">h2</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">),</span> <span class="string">"blue"</span><span class="special">);</span>

  <span class="comment">// 3D histogram, but only 2D index</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> <span class="comment">// out, red</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// out, blue</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// in, red</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">h2</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span> <span class="comment">// in, blue</span>
<span class="special">}</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="histogram.guide.expert.user_defined_storage_class"></a><a class="link" href="guide.html#histogram.guide.expert.user_defined_storage_class" title="User-defined storage class">User-defined
        storage class</a>
</h4></div></div></div>
<p>
          Histograms which use a different storage class can easily created with
          the factory function <code class="computeroutput"><a class="link" href="reference.html#header.boost.histogram.make_histogram_hpp" title="Header &lt;boost/histogram/make_histogram.hpp&gt;">make_histogram_with</a></code>.
          For convenience, this factory function accepts many standard containers
          as storage backends: vectors, arrays, and maps. These are automatically
          wrapped with a <code class="computeroutput"><a class="link" href="../boost/histogram/storage_adaptor.html" title="Class template storage_adaptor">boost::histogram::storage_adaptor</a></code>
          to provide the storage interface needed by the library. Users may also
          place custom accumulators in the vector, as described in the next section.
        </p>
<div class="warning"><table border="0" summary="Warning">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../doc/src/images/warning.png"></td>
<th align="left">Warning</th>
</tr>
<tr><td align="left" valign="top"><p>
            The no-overflow-guarantee is only valid if the <code class="computeroutput"><a class="link" href="../boost/histogram/unlimited_storage.html" title="Class template unlimited_storage">unlimited_storage</a></code>
            (the default) is used. If you change the storage policy, you need to
            know what you are doing.
          </p></td></tr>
</table></div>
<p>
          A <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code> may provide higher performance
          than the <code class="computeroutput"><a class="link" href="../boost/histogram/unlimited_storage.html" title="Class template unlimited_storage">unlimited_storage</a></code>
          with a carefully chosen counter type. Usually, this would be an integral
          or floating point type. A <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>-based
          storage may be faster for low-dimensional histograms (or not, you need
          to measure).
        </p>
<p>
          Users who work exclusively with weighted histograms should chose a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span></code>,
          it will be faster. If they also want to track the variance of the sum of
          weights, a vector-based storage of <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/weighted_sum.html" title="Class template weighted_sum">weighted_sum</a></code>
          accumulators should be used. The factory function <code class="computeroutput"><a class="link" href="../boost/histogram/make_wei_idm45537378925680.html" title="Function template make_weighted_histogram">make_weighted_histogram</a></code>
          is a convenient way to generate a histogram with this storage.
        </p>
<p>
          An interesting alternative to a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>
          is to use a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span></code>. The latter provides a storage
          with a fixed maximum capacity (the size of the array). <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span></code>
          allocates the memory on the stack. In combination with a static axis configuration
          this allows one to create histograms completely on the stack without any
          dynamic memory allocation. Small stack-based histograms can be created
          and destroyed very fast.
        </p>
<p>
          Finally, a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span></code> or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">unordered_map</span></code>
          or any other map type that implements the STL interface can be used to
          generate a histogram with a sparse storage, where empty cells do not consume
          any memory. This sounds attractive, but the memory consumption per cell
          in such a data structure is much larger than for a vector or array, so
          the number of empty cells must be substantial to gain. Moreover, cell lookup
          in a sparse data structure may be less performant. Whether a sparse storage
          performs better than a dense storage depends on the use case. The library
          makes it easy to switch from dense to sparse storage and back, so users
          are invited to test both options.
        </p>
<p>
          The following example shows how histograms are constructed which use an
          alternative storage classes.
        </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">algorithm</span><span class="special">&gt;</span> <span class="comment">// std::for_each</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">array</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">/</span><span class="identifier">algorithm</span><span class="special">/</span><span class="identifier">sum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">functional</span><span class="special">&gt;</span> <span class="comment">// std::ref</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">unordered_map</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
  <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">axis</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">regular</span><span class="special">&lt;&gt;(</span><span class="number">10</span><span class="special">,</span> <span class="number">0.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">);</span>

  <span class="keyword">auto</span> <span class="identifier">data</span> <span class="special">=</span> <span class="special">{</span><span class="number">0.1</span><span class="special">,</span> <span class="number">0.3</span><span class="special">,</span> <span class="number">0.2</span><span class="special">,</span> <span class="number">0.7</span><span class="special">};</span>

  <span class="comment">// Create static histogram with vector&lt;int&gt; as counter storage, you can use</span>
  <span class="comment">// other arithmetic types as counters, e.g. double.</span>
  <span class="keyword">auto</span> <span class="identifier">h1</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(),</span> <span class="identifier">axis</span><span class="special">);</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">data</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">data</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">h1</span><span class="special">));</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">h1</span><span class="special">)</span> <span class="special">==</span> <span class="number">4</span><span class="special">);</span>

  <span class="comment">// Create static histogram with array&lt;int, N&gt; as counter storage which is</span>
  <span class="comment">// allocated completely on the stack (this is very fast). N may be larger than</span>
  <span class="comment">// the actual number of bins used; an exception is raised if N is too small to</span>
  <span class="comment">// hold all bins.</span>
  <span class="keyword">auto</span> <span class="identifier">h2</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">12</span><span class="special">&gt;(),</span> <span class="identifier">axis</span><span class="special">);</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">data</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">data</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">h2</span><span class="special">));</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">h2</span><span class="special">)</span> <span class="special">==</span> <span class="number">4</span><span class="special">);</span>

  <span class="comment">// Create static histogram with unordered_map as counter storage; this</span>
  <span class="comment">// generates a sparse histogram where only memory is allocated for bins that</span>
  <span class="comment">// are non-zero. This sounds like a good idea for high-dimensional histograms,</span>
  <span class="comment">// but maps come with a memory and run-time overhead. The default_storage</span>
  <span class="comment">// usually performs better in high dimensions.</span>
  <span class="keyword">auto</span> <span class="identifier">h3</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">unordered_map</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&gt;(),</span> <span class="identifier">axis</span><span class="special">);</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">data</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">data</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">h3</span><span class="special">));</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">h3</span><span class="special">)</span> <span class="special">==</span> <span class="number">4</span><span class="special">);</span>
<span class="special">}</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="histogram.guide.expert.parallelisation_options"></a><a class="link" href="guide.html#histogram.guide.expert.parallelisation_options" title="Parallelisation options">Parallelisation
        options</a>
</h4></div></div></div>
<p>
          There are two ways to generate a single histogram using several threads.
        </p>
<p>
          1. Each thread has its own copy of the histogram. Each copy is independently
          filled. The copies are then added in the main thread. Use this as the default
          when you can afford having <code class="computeroutput"><span class="identifier">N</span></code>
          copies of the histogram in memory for <code class="computeroutput"><span class="identifier">N</span></code>
          threads, because it allows each thread to work on its thread-local memory
          and utilise the CPU cache without the need to synchronise memory access.
          The highest performance gains are obtained in this way.
        </p>
<p>
          2. There is only one histogram which is filled concurrently by several
          threads. This requires using a thread-safe storage that can handle concurrent
          writes. The library provides the <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/count.html" title="Class template count">boost::histogram::accumulators::count</a></code>
          accumulator with a thread-safe option, which combined with the <code class="computeroutput"><a class="link" href="reference.html#boost.histogram.dense_storage">boost::histogram::dense_storage</a></code>
          provides a thread-safe storage.
        </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
            Filling a histogram with growing axes in a multi-threaded environment
            is safe, but has poor performance since the histogram must be locked
            on each fill. The locks are required because an axis could grow each
            time, which changes the number of cells and cell addressing for all other
            threads. Even without growing axes, there is only a performance gain
            if the histogram is either very large or when significant time is spend
            in preparing the value to fill. For small histograms, threads frequently
            access the same cell, whose state has to be synchronised between the
            threads. This is slow even with atomic counters and made worse by the
            effect of false sharing.
          </p></td></tr>
</table></div>
<p>
          The next example demonstrates option 2 (option 1 is straight-forward to
          implement).
        </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">/</span><span class="identifier">algorithm</span><span class="special">/</span><span class="identifier">sum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">functional</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">thread</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&gt;</span>

<span class="comment">// dummy fill function, to be executed in parallel by several threads</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Histogram</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">fill</span><span class="special">(</span><span class="identifier">Histogram</span><span class="special">&amp;</span> <span class="identifier">h</span><span class="special">)</span> <span class="special">{</span>
  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">1000</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">h</span><span class="special">(</span><span class="identifier">i</span> <span class="special">%</span> <span class="number">10</span><span class="special">);</span> <span class="special">}</span>
<span class="special">}</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="comment">/*
    Create histogram with container of thread-safe counters for parallel filling in
    several threads. Only filling is thread-safe, other guarantees are not given.
  */</span>
  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">dense_storage</span><span class="special">&lt;</span><span class="identifier">accumulators</span><span class="special">::</span><span class="identifier">count</span><span class="special">&lt;</span><span class="keyword">unsigned</span><span class="special">,</span> <span class="keyword">true</span><span class="special">&gt;&gt;(),</span>
                               <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">10</span><span class="special">));</span>

  <span class="comment">/*
    Run the fill function in parallel from different threads. This is safe when a
    thread-safe accumulator and a storage with thread-safe cell access are used.
  */</span>
  <span class="keyword">auto</span> <span class="identifier">fill_h</span> <span class="special">=</span> <span class="special">[&amp;</span><span class="identifier">h</span><span class="special">]()</span> <span class="special">{</span> <span class="identifier">fill</span><span class="special">(</span><span class="identifier">h</span><span class="special">);</span> <span class="special">};</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">t1</span><span class="special">(</span><span class="identifier">fill_h</span><span class="special">);</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">t2</span><span class="special">(</span><span class="identifier">fill_h</span><span class="special">);</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">t3</span><span class="special">(</span><span class="identifier">fill_h</span><span class="special">);</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">t4</span><span class="special">(</span><span class="identifier">fill_h</span><span class="special">);</span>
  <span class="identifier">t1</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span>
  <span class="identifier">t2</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span>
  <span class="identifier">t3</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span>
  <span class="identifier">t4</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span>

  <span class="comment">// Without a thread-safe accumulator, this number may be smaller.</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">algorithm</span><span class="special">::</span><span class="identifier">sum</span><span class="special">(</span><span class="identifier">h</span><span class="special">)</span> <span class="special">==</span> <span class="number">4000</span><span class="special">);</span>
<span class="special">}</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="histogram.guide.expert.user_defined_accumulators"></a><a class="link" href="guide.html#histogram.guide.expert.user_defined_accumulators" title="User-defined accumulators">User-defined
        accumulators</a>
</h4></div></div></div>
<p>
          A storage can hold custom accumulators which can accept an arbitrary number
          of arguments. The arguments are passed to the accumulator via the <code class="computeroutput"><a class="link" href="../boost/histogram/sample.html" title="Function template sample">sample</a></code> call, for example,
          <code class="computeroutput"><span class="identifier">sample</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span></code>
          for an accumulator which accepts three arguments. Custom accumulators can
          be combined with any container supported by <code class="computeroutput"><a class="link" href="../boost/histogram/storage_adaptor.html" title="Class template storage_adaptor">boost::histogram::storage_adaptor</a></code>.
          For convenience, the alias template <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">::</span><span class="identifier">dense_storage</span></code>
          is provided to make a standard storage with a custom accumulator type.
        </p>
<p>
          The library provides several accumulators:
        </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
              <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/sum.html" title="Class template sum">sum</a></code>
              accepts no samples, but accepts a weight. It is an alternative to a
              plain arithmetic type as a counter. It provides an advantage when histograms
              are filled with weights that differ dramatically in magnitude. The
              sum of weights is computed incrementally with the Neumaier algorithm.
              The algorithm is more accurate, but consumes more CPU and memory (memory
              is doubled compared to a normal sum of floating point numbers).
            </li>
<li class="listitem">
              <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/weighted_sum.html" title="Class template weighted_sum">weighted_sum</a></code>
              accepts no samples, but accepts a weight. It computes the sum of weights
              and the sum of weights squared, the variance estimate of the sum of
              weights. This type is used by the <code class="computeroutput"><a class="link" href="../boost/histogram/make_wei_idm45537378925680.html" title="Function template make_weighted_histogram">make_weighted_histogram</a></code>.
            </li>
<li class="listitem">
              <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/mean.html" title="Class template mean">mean</a></code>
              accepts a sample and computes the mean of the samples. <code class="computeroutput"><a class="link" href="../boost/histogram/make_pro_idm45537378910608.html" title="Function template make_profile">make_profile</a></code> uses
              this accumulator.
            </li>
<li class="listitem">
              <code class="computeroutput"><a class="link" href="../boost/histogram/accumulators/weighted_mean.html" title="Class template weighted_mean">weighted_mean</a></code>
              accepts a sample and a weight. It computes the weighted mean of the
              samples. <code class="computeroutput"><a class="link" href="../boost/histogram/make_wei_idm45537378898048.html" title="Function template make_weighted_profile">make_weighted_profile</a></code>
              uses this accumulator.
            </li>
</ul></div>
<p>
          Users can easily write their own accumulators and plug them into the histogram,
          if they adhere to the <a class="link" href="concepts.html#histogram.concepts.Accumulator" title="Accumulator"><span class="bold"><strong>Accumulator</strong></span> concept</a>. All accumulators from
          <a href="../../../../../libs/accumulators/index.html" target="_top">Boost.Accumulators</a>
          that accept a single argument and no weights work out of the box. Other
          accumulators from Boost.Accumulators can be made to work by using them
          inside a wrapper class that implements the concept.
        </p>
<p>
          The first example shows how to make and use a histogram that uses one of
          the the builtin accumulators.
        </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">format</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>
  <span class="keyword">using</span> <span class="identifier">mean</span> <span class="special">=</span> <span class="identifier">accumulators</span><span class="special">::</span><span class="identifier">mean</span><span class="special">&lt;&gt;;</span>

  <span class="comment">// Create a 1D-profile, which computes the mean of samples in each bin.</span>
  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">dense_storage</span><span class="special">&lt;</span><span class="identifier">mean</span><span class="special">&gt;(),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">));</span>
  <span class="comment">// The factory function `make_profile` is provided as a shorthand for this, so this is</span>
  <span class="comment">// equivalent to the previous line: auto h = make_profile(axis::integer&lt;&gt;(0, 2));</span>

  <span class="comment">// An argument marked as `sample` is passed to the accumulator.</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">1</span><span class="special">));</span> <span class="comment">// sample goes to first cell</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">2</span><span class="special">));</span> <span class="comment">// sample goes to first cell</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">3</span><span class="special">));</span> <span class="comment">// sample goes to second cell</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">4</span><span class="special">));</span> <span class="comment">// sample goes to second cell</span>

  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span>
    <span class="comment">// Accumulators usually have methods to access their state. Use the arrow</span>
    <span class="comment">// operator to access them. Here, `count()` gives the number of samples,</span>
    <span class="comment">// `value()` the mean, and `variance()` the variance estimate of the mean.</span>
    <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"index %i count %i mean %.1f variance %.1f\n"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">()</span> <span class="special">%</span>
              <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">count</span><span class="special">()</span> <span class="special">%</span> <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">()</span> <span class="special">%</span> <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">variance</span><span class="special">();</span>
  <span class="special">}</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"index 0 count 2 mean 1.5 variance 0.5\n"</span>
                     <span class="string">"index 1 count 2 mean 3.5 variance 0.5\n"</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
          The simplest way to make a custom accumulator is to inherit from one of
          the builtin accumulators. The following example shows how to add arbitrary
          metadata to each histogram cell by inheriting a custom accumulator from
          a builtin accumulator.
        </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cmath</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="comment">// derive custom accumulator from one of the builtins</span>
  <span class="keyword">struct</span> <span class="identifier">accumulator_with_metadata</span> <span class="special">:</span> <span class="identifier">accumulators</span><span class="special">::</span><span class="identifier">count</span><span class="special">&lt;&gt;</span> <span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">meta</span><span class="special">;</span> <span class="comment">// custom meta data</span>

    <span class="comment">// arbitrary additional data and interface could be added here</span>
  <span class="special">};</span>

  <span class="comment">// make 1D histogram with custom accmulator</span>
  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">dense_storage</span><span class="special">&lt;</span><span class="identifier">accumulator_with_metadata</span><span class="special">&gt;(),</span>
                               <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">));</span>

  <span class="comment">// fill some weighted entries</span>
  <span class="keyword">auto</span> <span class="identifier">x</span> <span class="special">=</span> <span class="special">{</span><span class="number">1</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">1</span><span class="special">};</span>
  <span class="identifier">h</span><span class="special">.</span><span class="identifier">fill</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>

  <span class="comment">// assigning meta data to two bins</span>
  <span class="identifier">h</span><span class="special">[</span><span class="number">0</span><span class="special">].</span><span class="identifier">meta</span> <span class="special">=</span> <span class="string">"Foo"</span><span class="special">;</span>
  <span class="identifier">h</span><span class="special">[</span><span class="number">2</span><span class="special">].</span><span class="identifier">meta</span> <span class="special">=</span> <span class="string">"Bar"</span><span class="special">;</span>

  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span>
    <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">bin</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">" value "</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">" meta "</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">meta</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>

  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"1 value 2 meta Foo\n"</span>
                     <span class="string">"2 value 1 meta \n"</span>
                     <span class="string">"3 value 0 meta Bar\n"</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
          The next example shows how to making a custom accumulators completely from
          scratch. The library was designed to make this as easy as possible.
        </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">format</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="comment">// A custom accumulator which tracks the maximum of the samples.</span>
  <span class="comment">// It must have a call operator that accepts the argument of the `sample` function.</span>
  <span class="keyword">struct</span> <span class="identifier">maximum</span> <span class="special">{</span>
    <span class="comment">// return value is ignored, so we use void</span>
    <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">double</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span>
      <span class="keyword">if</span> <span class="special">(</span><span class="identifier">x</span> <span class="special">&gt;</span> <span class="identifier">value</span><span class="special">)</span> <span class="identifier">value</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">;</span>
    <span class="special">}</span>
    <span class="keyword">double</span> <span class="identifier">value</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="comment">// value is public and initialized to zero</span>
  <span class="special">};</span>

  <span class="comment">// Create 1D histogram that uses the custom accumulator.</span>
  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">dense_storage</span><span class="special">&lt;</span><span class="identifier">maximum</span><span class="special">&gt;(),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">));</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">1.0</span><span class="special">));</span> <span class="comment">// sample goes to first cell</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">2.0</span><span class="special">));</span> <span class="comment">// sample goes to first cell</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">3.0</span><span class="special">));</span> <span class="comment">// sample goes to second cell</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">4.0</span><span class="special">));</span> <span class="comment">// sample goes to second cell</span>

  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span>
    <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"index %i maximum %.1f\n"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">index</span><span class="special">()</span> <span class="special">%</span> <span class="identifier">x</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">;</span>
  <span class="special">}</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"index 0 maximum 2.0\n"</span>
                     <span class="string">"index 1 maximum 4.0\n"</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
          The next example shows a more complex custom accumulator that accepts two
          samples at once and an optional weight. It independently computes the mean
          for each sample. This is more efficient than filling two separate profiles,
          because the cell lookup has to be done only once.
        </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">format</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="comment">// Accumulator accepts two samples and an optional weight and computes the mean of each.</span>
  <span class="keyword">struct</span> <span class="identifier">multi_mean</span> <span class="special">{</span>
    <span class="identifier">accumulators</span><span class="special">::</span><span class="identifier">mean</span><span class="special">&lt;&gt;</span> <span class="identifier">mx</span><span class="special">,</span> <span class="identifier">my</span><span class="special">;</span>

    <span class="comment">// called when no weight is passed</span>
    <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">double</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span>
      <span class="identifier">mx</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
      <span class="identifier">my</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span>
    <span class="special">}</span>

    <span class="comment">// called when a weight is passed</span>
    <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">weight_type</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">w</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span>
      <span class="identifier">mx</span><span class="special">(</span><span class="identifier">w</span><span class="special">,</span> <span class="identifier">x</span><span class="special">);</span>
      <span class="identifier">my</span><span class="special">(</span><span class="identifier">w</span><span class="special">,</span> <span class="identifier">y</span><span class="special">);</span>
    <span class="special">}</span>
  <span class="special">};</span>
  <span class="comment">// Note: The implementation can be made more efficient by sharing the sum of weights.</span>

  <span class="comment">// Create a 1D histogram that uses the custom accumulator.</span>
  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">dense_storage</span><span class="special">&lt;</span><span class="identifier">multi_mean</span><span class="special">&gt;(),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">));</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">));</span>            <span class="comment">// samples go to first cell</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">3</span><span class="special">,</span> <span class="number">4</span><span class="special">));</span>            <span class="comment">// samples go to first cell</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">5</span><span class="special">,</span> <span class="number">6</span><span class="special">),</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">2</span><span class="special">));</span> <span class="comment">// samples go to second cell</span>
  <span class="identifier">h</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="number">7</span><span class="special">,</span> <span class="number">8</span><span class="special">),</span> <span class="identifier">weight</span><span class="special">(</span><span class="number">3</span><span class="special">));</span> <span class="comment">// samples go to second cell</span>

  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">bin</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span>
    <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"index %i mean-x %.1f mean-y %.1f\n"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">bin</span><span class="special">.</span><span class="identifier">index</span><span class="special">()</span> <span class="special">%</span>
              <span class="identifier">bin</span><span class="special">-&gt;</span><span class="identifier">mx</span><span class="special">.</span><span class="identifier">value</span><span class="special">()</span> <span class="special">%</span> <span class="identifier">bin</span><span class="special">-&gt;</span><span class="identifier">my</span><span class="special">.</span><span class="identifier">value</span><span class="special">();</span>
  <span class="special">}</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"index 0 mean-x 2.0 mean-y 3.0\n"</span>
                     <span class="string">"index 1 mean-x 6.2 mean-y 7.2\n"</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
          And finally, just for fun, we use a histogram as the accumulator for another
          histogram.
        </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">histogram</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cmath</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">sstream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">histogram</span><span class="special">;</span>

  <span class="comment">// First we define the nested histogram type.</span>
  <span class="keyword">using</span> <span class="identifier">axis_t</span> <span class="special">=</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">category</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">null_type</span><span class="special">,</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">option</span><span class="special">::</span><span class="identifier">growth_t</span><span class="special">&gt;;</span>
  <span class="keyword">using</span> <span class="identifier">base_t</span> <span class="special">=</span> <span class="identifier">histogram</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">axis_t</span><span class="special">&gt;&gt;;</span>

  <span class="comment">// Now we make an accumulator out of it by using inheritance.</span>
  <span class="comment">// We only need to implement operator(). A matching version of operator() is actually</span>
  <span class="comment">// present in base_t, but it is templated and this is not allowed by the accumulator</span>
  <span class="comment">// concept. Initialization could also happen here. We don't need to initialize anything</span>
  <span class="comment">// here, because the default constructor of base_t is called automatically and</span>
  <span class="comment">// sufficient for this example.</span>
  <span class="keyword">struct</span> <span class="identifier">hist_t</span> <span class="special">:</span> <span class="identifier">base_t</span> <span class="special">{</span>
    <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">const</span> <span class="keyword">double</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">base_t</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()(</span><span class="identifier">x</span><span class="special">);</span> <span class="special">}</span>
  <span class="special">};</span>

  <span class="keyword">auto</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">make_histogram_with</span><span class="special">(</span><span class="identifier">dense_storage</span><span class="special">&lt;</span><span class="identifier">hist_t</span><span class="special">&gt;(),</span> <span class="identifier">axis</span><span class="special">::</span><span class="identifier">integer</span><span class="special">&lt;&gt;(</span><span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">));</span>

  <span class="keyword">auto</span> <span class="identifier">x</span> <span class="special">=</span> <span class="special">{</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">2</span><span class="special">};</span>
  <span class="keyword">auto</span> <span class="identifier">s</span> <span class="special">=</span> <span class="special">{</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">3</span><span class="special">};</span> <span class="comment">// samples are filled into the nested histograms</span>
  <span class="identifier">h</span><span class="special">.</span><span class="identifier">fill</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">sample</span><span class="special">(</span><span class="identifier">s</span><span class="special">));</span>

  <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">os</span><span class="special">;</span>
  <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(</span><span class="identifier">h</span><span class="special">))</span> <span class="special">{</span>
    <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">bin</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">" "</span><span class="special">;</span>
    <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span><span class="special">&amp;&amp;</span> <span class="identifier">y</span> <span class="special">:</span> <span class="identifier">indexed</span><span class="special">(*</span><span class="identifier">x</span><span class="special">))</span> <span class="special">{</span> <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="string">"("</span> <span class="special">&lt;&lt;</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">bin</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">": "</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">y</span> <span class="special">&lt;&lt;</span> <span class="string">") "</span><span class="special">;</span> <span class="special">}</span>
    <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
  <span class="special">}</span>

  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
  <span class="identifier">assert</span><span class="special">(</span><span class="identifier">os</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"1 (1: 1) (2: 1) \n"</span>
                     <span class="string">"2 (3: 2) \n"</span>
                     <span class="string">"3 \n"</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
          Note that the axis size of the nested histogram differs from bin to bin.
          Creating a 2D histogram in this way is not as efficient as the normal way,
          but it allows one to create a histograms with such a non-rectangular layout
          of cells.
        </p>
</div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2016-2019 Hans
      Dembinski<p>
        Distributed under the Boost Software License, Version 1.0. (See accompanying
        file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
      </p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="getting_started.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="benchmarks.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>
